# This patch strips out code that is currently unused from the upstream
# AWS SDK, this code is not needed to support AWS auth methods
# and adds little outside of extra code to bazel 
diff -Nau8r ./src/main/java/com/amazonaws/AbortedException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AbortedException.java
--- ./src/main/java/com/amazonaws/AbortedException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AbortedException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-/**
- * SDK operation aborted exception.
- */
-public class AbortedException extends SdkClientException {
-    private static final long serialVersionUID = 1L;
-
-    public AbortedException(String message, Throwable t) {
-        super(message, t);
-    }
-
-    public AbortedException(Throwable t) {
-        super("", t);
-    }
-
-    public AbortedException(String message) {
-        super(message);
-    }
-
-    public AbortedException() {
-        super("");
-    }
-
-    /**
-     * {@inheritDoc}
-     * An aborted exception is not intended to be retried.
-     */
-    @Override
-    public boolean isRetryable() {
-        return false;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/adapters/types/StringToByteBufferAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/adapters/types/StringToByteBufferAdapter.java
--- ./src/main/java/com/amazonaws/adapters/types/StringToByteBufferAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/adapters/types/StringToByteBufferAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,35 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.adapters.types;
-
-import java.nio.ByteBuffer;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.util.StringUtils;
-
-@SdkProtectedApi
-public class StringToByteBufferAdapter implements TypeAdapter<String, ByteBuffer> {
-
-    @Override
-    public ByteBuffer adapt(String source) {
-        if (source == null) {
-            return null;
-        } else {
-            return ByteBuffer.wrap(source.getBytes(StringUtils.UTF8));
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/adapters/types/StringToInputStreamAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/adapters/types/StringToInputStreamAdapter.java
--- ./src/main/java/com/amazonaws/adapters/types/StringToInputStreamAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/adapters/types/StringToInputStreamAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,39 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.adapters.types;
-
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.util.StringInputStream;
-
-@SdkProtectedApi
-public class StringToInputStreamAdapter implements TypeAdapter<String, InputStream> {
-
-    @Override
-    public InputStream adapt(String source) {
-        if (source == null) {
-            return null;
-        }
-        try {
-            return new StringInputStream(source);
-        } catch (UnsupportedEncodingException e) {
-            throw new SdkClientException(e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/adapters/types/TypeAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/adapters/types/TypeAdapter.java
--- ./src/main/java/com/amazonaws/adapters/types/TypeAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/adapters/types/TypeAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,33 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.adapters.types;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Adapter interface to convert one type to another
- *
- * @param <Source>
- *            Source type
- * @param <Destination>
- *            Destination type
- */
-@SdkInternalApi
-public interface TypeAdapter<Source, Destination> {
-
-    Destination adapt(Source source);
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/AmazonWebServiceClient.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceClient.java
--- ./src/main/java/com/amazonaws/AmazonWebServiceClient.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceClient.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,964 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import static com.amazonaws.SDKGlobalConfiguration.PROFILING_SYSTEM_PROPERTY;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.auth.EndpointPrefixAwareSigner;
-import com.amazonaws.auth.RegionAwareSigner;
-import com.amazonaws.auth.Signer;
-import com.amazonaws.auth.SignerFactory;
-import com.amazonaws.client.AwsSyncClientParams;
-import com.amazonaws.client.builder.AwsClientBuilder;
-import com.amazonaws.handlers.RequestHandler;
-import com.amazonaws.handlers.RequestHandler2;
-import com.amazonaws.http.AmazonHttpClient;
-import com.amazonaws.http.ExecutionContext;
-import com.amazonaws.internal.DefaultServiceEndpointBuilder;
-import com.amazonaws.internal.auth.DefaultSignerProvider;
-import com.amazonaws.internal.auth.SignerProvider;
-import com.amazonaws.internal.auth.SignerProviderContext;
-import com.amazonaws.log.CommonsLogFactory;
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.metrics.RequestMetricCollector;
-import com.amazonaws.regions.Region;
-import com.amazonaws.regions.Regions;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.AWSRequestMetrics.Field;
-import com.amazonaws.util.AwsHostNameUtils;
-import com.amazonaws.util.Classes;
-import com.amazonaws.util.RuntimeHttpUtils;
-import com.amazonaws.util.StringUtils;
-import java.net.URI;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Abstract base class for Amazon Web Service Java clients.
- * <p>
- * Responsible for basic client capabilities that are the same across all AWS
- * SDK Java clients (ex: setting the client endpoint).
- */
-public abstract class AmazonWebServiceClient {
-
-    /**
-     * @deprecated No longer used.
-     */
-    @Deprecated
-    public static final boolean LOGGING_AWS_REQUEST_METRIC = true;
-
-    private static final String AMAZON = "Amazon";
-    private static final String AWS = "AWS";
-
-    private static final Log log =
-        LogFactory.getLog(AmazonWebServiceClient.class);
-
-    static {
-        // Configures the internal logging of the signers and core
-        // classes to use Jakarta Commons Logging to stay consistent with the
-        // rest of the library.
-        boolean success = com.amazonaws.log.InternalLogFactory.configureFactory(
-                            new CommonsLogFactory());
-        if (log.isDebugEnabled())
-            log.debug("Internal logging successfully configured to commons logger: "
-                    + success);
-    }
-
-    /**
-     * Flag indicating whether a client is mutable or not. Legacy clients built via the constructors
-     * are mutable. Clients built with the fluent builders are immutable.
-     */
-    private volatile boolean isImmutable = false;
-
-    /**
-     * The service endpoint to which this client will send requests.
-     * <p>
-     * Subclass should only read but not assign to this field, at least not
-     * without synchronization on the enclosing object for thread-safety
-     * reason.
-     */
-    protected volatile URI endpoint;
-
-    /**
-     * Used to explicitly override the internal signer region computed by the
-     * default implementation. This field is typically null.
-     */
-    private volatile String signerRegionOverride;
-
-    /** The client configuration */
-    protected ClientConfiguration clientConfiguration;
-
-    /** Low level client for sending requests to AWS services. */
-    protected AmazonHttpClient client;
-
-    /** Optional request handlers for additional request processing. */
-    protected final List<RequestHandler2> requestHandler2s;
-
-    /** Optional offset (in seconds) to use when signing requests */
-    protected int timeOffset;
-
-    private volatile SignerProvider signerProvider;
-
-    /**
-     * The cached service abbreviation for this service, used for identifying
-     * service endpoints by region, identifying the necessary signer, etc.
-     * Thread safe so it's backward compatible.
-     */
-    private volatile String serviceName;
-
-    /**
-     * The service name in region metadata, i.e. the prefix of endpoint.
-     */
-    private volatile String endpointPrefix;
-
-    /**
-     * Region used to sign requests.
-     */
-    private volatile String signingRegion;
-
-    /**
-     * Constructs a new AmazonWebServiceClient object using the specified
-     * configuration.
-     *
-     * @param clientConfiguration
-     *            The client configuration for this client.
-     */
-    public AmazonWebServiceClient(ClientConfiguration clientConfiguration) {
-        this(clientConfiguration, null);
-    }
-
-    /**
-     * Constructs a new AmazonWebServiceClient object using the specified
-     * configuration and request metric collector.
-     *
-     * @param clientConfiguration
-     *            The client configuration for this client.
-     * @param requestMetricCollector
-     *            optional request metric collector to be used at the http
-     *            client level; can be null.
-     */
-    public AmazonWebServiceClient(ClientConfiguration clientConfiguration,
-            RequestMetricCollector requestMetricCollector) {
-        this(clientConfiguration, requestMetricCollector, false);
-    }
-
-    @SdkProtectedApi
-    protected AmazonWebServiceClient(ClientConfiguration clientConfiguration,
-                                     RequestMetricCollector requestMetricCollector,
-                                     boolean disableStrictHostNameVerification) {
-        this.clientConfiguration = clientConfiguration;
-        requestHandler2s = new CopyOnWriteArrayList<RequestHandler2>();
-        client = new AmazonHttpClient(clientConfiguration,
-                requestMetricCollector, disableStrictHostNameVerification,
-                calculateCRC32FromCompressedData());
-    }
-
-    protected AmazonWebServiceClient(AwsSyncClientParams clientParams) {
-        this.clientConfiguration = clientParams.getClientConfiguration();
-        requestHandler2s = clientParams.getRequestHandlers();
-        client = new AmazonHttpClient(clientConfiguration, clientParams.getRequestMetricCollector(),
-                                      !useStrictHostNameVerification(),
-                                      calculateCRC32FromCompressedData());
-    }
-
-    /**
-     * Returns the signer.
-     * <p>
-     * Note, however, the signer configured for S3 is incomplete at this stage
-     * as the information on the S3 bucket and key is not yet known.
-     */
-    @Deprecated
-    protected Signer getSigner() {
-        return signerProvider.getSigner(SignerProviderContext.builder().build());
-    }
-
-    /**
-     * @return Current SignerProvider instance.
-     */
-    @SdkProtectedApi
-    protected SignerProvider getSignerProvider() {
-        return signerProvider;
-    }
-
-    /**
-     * Overrides the default endpoint for this client. Callers can use this
-     * method to control which AWS region they want to work with.
-     * <p>
-     * <b>This method is not threadsafe. Endpoints should be configured when the
-     * client is created and before any service requests are made. Changing it
-     * afterwards creates inevitable race conditions for any service requests in
-     * transit.</b>
-     * <p>
-     * Callers can pass in just the endpoint (ex: "ec2.amazonaws.com") or a full
-     * URL, including the protocol (ex: "https://ec2.amazonaws.com"). If the
-     * protocol is not specified here, the default protocol from this client's
-     * {@link ClientConfiguration} will be used, which by default is HTTPS.
-     * <p>
-     * For more information on using AWS regions with the AWS SDK for Java, and
-     * a complete list of all available endpoints for all AWS services, see:
-     * <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3912">
-     * http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3912</a>
-     *
-     * @param endpoint
-     *            The endpoint (ex: "ec2.amazonaws.com") or a full URL,
-     *            including the protocol (ex: "https://ec2.amazonaws.com") of
-     *            the region specific AWS endpoint this client will communicate
-     *            with.
-     * @throws IllegalArgumentException
-     *             If any problems are detected with the specified endpoint.
-     *
-     * @deprecated use {@link AwsClientBuilder#setEndpointConfiguration(AwsClientBuilder.EndpointConfiguration)} for example:
-     * {@code builder.setEndpointConfiguration(new EndpointConfiguration(endpoint, signingRegion));}
-     */
-    @Deprecated
-    public void setEndpoint(String endpoint) throws IllegalArgumentException {
-        checkMutability();
-        URI uri = toURI(endpoint);
-        Signer signer = computeSignerByURI(uri, signerRegionOverride, false);
-        synchronized (this) {
-            this.endpoint = uri;
-            this.signerProvider = createSignerProvider(signer);
-            this.signingRegion = AwsHostNameUtils.parseRegion(endpoint, getEndpointPrefix());
-        }
-    }
-
-    /** Returns the endpoint as a URI. */
-    private URI toURI(String endpoint) throws IllegalArgumentException {
-        return RuntimeHttpUtils.toUri(endpoint, clientConfiguration);
-    }
-
-    /**
-     * Allows specifying the endpoint along with signing information (service name and signing region). This method will
-     * overwrite any information set previously by any set/with/configure Region/Endpoint methods.
-     * <p>
-     * Overrides the default endpoint for this client
-     * ("http://dynamodb.us-east-1.amazonaws.com/") and explicitly provides an
-     * AWS region ID and AWS service name to use when the client calculates a
-     * signature for requests. In almost all cases, this region ID and service
-     * name are automatically determined from the endpoint, and callers should
-     * use the simpler one-argument form of setEndpoint instead of this method.
-     * <p>
-     * Callers can pass in just the endpoint (ex:
-     * "dynamodb.us-east-1.amazonaws.com/") or a full URL, including the
-     * protocol (ex: "http://dynamodb.us-east-1.amazonaws.com/"). If the
-     * protocol is not specified here, the default protocol from this client's
-     * {@link ClientConfiguration} will be used, which by default is HTTPS.
-     * <p>
-     * For more information on using AWS regions with the AWS SDK for Java, and
-     * a complete list of all available endpoints for all AWS services, see: <a
-     * href=
-     * "http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3912"
-     * > http://developer.amazonwebservices.com/connect/entry.jspa?externalID=
-     * 3912</a>
-     *
-     * @param endpoint
-     *            The endpoint (ex: "dynamodb.us-east-1.amazonaws.com/") or a
-     *            full URL, including the protocol (ex:
-     *            "http://dynamodb.us-east-1.amazonaws.com/") of the region
-     *            specific AWS endpoint this client will communicate with.
-     * @param serviceName
-     *            This parameter is ignored.
-     * @param regionId
-     *            The ID of the region in which this service resides AND the
-     *            overriding region for signing purposes.
-     *
-     * @throws IllegalArgumentException
-     *             If any problems are detected with the specified endpoint.
-     * @deprecated Please use the client builders instead. The
-     * {@link AwsClientBuilder#withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration)} method on the builder allows
-     * setting both endpoint and signing region. See
-     * <a href="http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/creating-clients.html">Creating Service Clients</a>
-     * for more information.
-     */
-    @Deprecated
-    public void setEndpoint(String endpoint, String serviceName, String regionId) {
-        URI uri = toURI(endpoint);
-        Signer signer = computeSignerByServiceRegion(serviceName, regionId,
-                                                     regionId, true);
-        synchronized (this) {
-            setServiceNameIntern(serviceName);
-            this.signerProvider = createSignerProvider(signer);
-            this.endpoint = uri;
-            this.signerRegionOverride = regionId;
-            this.signingRegion = regionId;
-        }
-    }
-
-    /**
-     * Returns the signer based on the given URI and the current AWS client
-     * configuration. Currently only the SQS client can have different region on
-     * a per request basis. For other AWS clients, the region remains the same
-     * on a per AWS client level.
-     * <p>
-     * Note, however, the signer returned for S3 is incomplete at this stage as
-     * the information on the S3 bucket and key is not yet known.
-     */
-    public Signer getSignerByURI(URI uri) {
-        return computeSignerByURI(uri, signerRegionOverride, true);
-    }
-
-    /**
-     * Returns the signer for the given uri and the current client
-     * configuration.
-     * <p>
-     * Note, however, the signer returned for S3 is incomplete at this stage as
-     * the information on the S3 bucket and key is not yet known.
-     *
-     * @param signerRegionOverride
-     *            the overriding signer region; or null if there is none.
-     * @param isRegionIdAsSignerParam
-     *            true if the "regionId" is used to configure the signer if
-     *            applicable; false if this method is called for the purpose of
-     *            purely setting the communication end point of this AWS client,
-     *            and therefore the "regionId" parameter will not be used
-     *            directly for configuring the signer.
-     */
-    private Signer computeSignerByURI(URI uri, String signerRegionOverride,
-            boolean isRegionIdAsSignerParam) {
-        if (uri == null) {
-            throw new IllegalArgumentException(
-                    "Endpoint is not set. Use setEndpoint to set an endpoint before performing any request.");
-        }
-        String service = getServiceNameIntern();
-        String region = AwsHostNameUtils.parseRegionName(uri.getHost(), getEndpointPrefix());
-        return computeSignerByServiceRegion(
-                service, region, signerRegionOverride, isRegionIdAsSignerParam);
-    }
-
-    /**
-     * Returns the signer for the given service name, region id, and the current
-     * client configuration.
-     * <p>
-     * Note, however, the signer returned for S3 is incomplete at this stage as
-     * the information on the S3 bucket and key is not yet known.
-     *
-     * @param regionId
-     *            the region for sending AWS requests
-     * @param signerRegionOverride
-     *            the overriding signer region; or null if there is none.
-     * @param isRegionIdAsSignerParam
-     *            true if the "regionId" is used to configure the signer if
-     *            applicable; false if this method is called for the purpose of
-     *            purely setting the communication end point of this AWS client,
-     *            and therefore the "regionId" parameter will not be used
-     *            directly for configuring the signer.
-     */
-    private Signer computeSignerByServiceRegion(
-            String serviceName, String regionId,
-            String signerRegionOverride,
-            boolean isRegionIdAsSignerParam) {
-        String signerType = clientConfiguration.getSignerOverride();
-        Signer signer = signerType == null
-             ? SignerFactory.getSigner(serviceName, regionId)
-             : SignerFactory.getSignerByTypeAndService(signerType, serviceName)
-             ;
-
-        if (signer instanceof RegionAwareSigner) {
-             // Overrides the default region computed
-             RegionAwareSigner regionAwareSigner = (RegionAwareSigner)signer;
-            // (signerRegionOverride != null) means that it is likely to be AWS
-            // internal dev work, as "signerRegionOverride" is typically null
-             // when used in the external release
-             if (signerRegionOverride != null)
-                 regionAwareSigner.setRegionName(signerRegionOverride);
-             else if (regionId != null && isRegionIdAsSignerParam)
-                 regionAwareSigner.setRegionName(regionId);
-         }
-
-         if (signer instanceof EndpointPrefixAwareSigner) {
-             EndpointPrefixAwareSigner endpointPrefixAwareSigner = (EndpointPrefixAwareSigner) signer;
-             /*
-              * This will be used to compute the region name required for signing
-              * if signerRegionOverride is not provided
-              */
-             endpointPrefixAwareSigner.setEndpointPrefix(endpointPrefix);
-         }
-
-         return signer;
-    }
-
-    /**
-     * An alternative to {@link AmazonWebServiceClient#setEndpoint(String)}, sets the regional
-     * endpoint for this client's service calls. Callers can use this method to control which AWS
-     * region they want to work with.
-     * <p>
-     * <b>This method is not threadsafe. A region should be configured when the client is created
-     * and before any service requests are made. Changing it afterwards creates inevitable race
-     * conditions for any service requests in transit or retrying.</b>
-     * <p>
-     * By default, all service endpoints in all regions use the https protocol. To use http instead,
-     * specify it in the {@link ClientConfiguration} supplied at construction.
-     *
-     * @param region
-     *            The region this client will communicate with. See
-     *            {@link Region#getRegion(com.amazonaws.regions.Regions)} for accessing a given
-     *            region.
-     * @throws java.lang.IllegalArgumentException
-     *             If the given region is null, or if this service isn't available in the given
-     *             region. See {@link Region#isServiceSupported(String)}
-     * @see Region#getRegion(com.amazonaws.regions.Regions)
-     * @see Region#createClient(Class, com.amazonaws.auth.AWSCredentialsProvider,
-     *      ClientConfiguration)
-     * @deprecated use {@link AwsClientBuilder#setRegion(String)}
-     */
-    @Deprecated
-    public void setRegion(Region region) throws IllegalArgumentException {
-        checkMutability();
-        if (region == null) {
-            throw new IllegalArgumentException("No region provided");
-        }
-        final String serviceNameForEndpoint = getEndpointPrefix();
-        final String serviceNameForSigner = getServiceNameIntern();
-        URI uri = new DefaultServiceEndpointBuilder(serviceNameForEndpoint, clientConfiguration.getProtocol()
-                .toString()).withRegion(region).getServiceEndpoint();
-        Signer signer = computeSignerByServiceRegion(serviceNameForSigner, region.getName(), signerRegionOverride, false);
-        synchronized (this) {
-            this.endpoint = uri;
-            this.signerProvider = createSignerProvider(signer);
-            this.signingRegion = AwsHostNameUtils.parseRegion(endpoint.toString(), getEndpointPrefix());
-        }
-    }
-
-    /**
-     * Convenient method for setting region.
-     *
-     * @param region region to set to; must not be null.
-     *
-     * @see #setRegion(Region)
-     * @deprecated use {@link AwsClientBuilder#setRegion(String)}
-     */
-    @Deprecated
-    public final void configureRegion(Regions region) {
-        checkMutability();
-        if (region == null)
-            throw new IllegalArgumentException("No region provided");
-        this.setRegion(Region.getRegion(region));
-    }
-
-    /**
-     * Shuts down this client object, releasing any resources that might be held
-     * open. This is an optional method, and callers are not expected to call
-     * it, but can if they want to explicitly release any open resources. Once a
-     * client has been shutdown, it should not be used to make any more
-     * requests.
-     */
-    public void shutdown() {
-        client.shutdown();
-    }
-
-    /**
-     * @deprecated by {@link #addRequestHandler(RequestHandler2)}.
-     *
-     * Appends a request handler to the list of registered handlers that are run
-     * as part of a request's lifecycle.
-     *
-     * @param requestHandler
-     *            The new handler to add to the current list of request
-     *            handlers.
-     */
-    @Deprecated
-    public void addRequestHandler(RequestHandler requestHandler) {
-        checkMutability();
-        requestHandler2s.add(RequestHandler2.adapt(requestHandler));
-    }
-
-    /**
-     * Appends a request handler to the list of registered handlers that are run
-     * as part of a request's lifecycle.
-     *
-     * @param requestHandler2
-     *            The new handler to add to the current list of request
-     *            handlers.
-     * @deprecated use {@link AwsClientBuilder#withRequestHandlers(RequestHandler2...)}
-     */
-    @Deprecated
-    public void addRequestHandler(RequestHandler2 requestHandler2) {
-        checkMutability();
-        requestHandler2s.add(requestHandler2);
-    }
-
-    /**
-     * Removes a request handler from the list of registered handlers that are run
-     * as part of a request's lifecycle.
-     *
-     * @param requestHandler
-     *            The handler to remove from the current list of request
-     *            handlers.
-     * @deprecated use {@link AwsClientBuilder#withRequestHandlers(RequestHandler2...)}
-     */
-    @Deprecated
-    public void removeRequestHandler(RequestHandler requestHandler) {
-        checkMutability();
-        requestHandler2s.remove(RequestHandler2.adapt(requestHandler));
-    }
-
-    /**
-     * @deprecated use {@link AwsClientBuilder#withRequestHandlers(RequestHandler2...)}
-     */
-    @Deprecated
-    public void removeRequestHandler(RequestHandler2 requestHandler2) {
-        checkMutability();
-        requestHandler2s.remove(requestHandler2);
-    }
-
-    /**
-     * Runs the {@code beforeMarshalling} method of any
-     * {@code RequestHandler2}s associated with this client.
-     *
-     * @param request the request passed in from the user
-     * @return the (possibly different) request to marshal
-     */
-    @SuppressWarnings("unchecked")
-    protected final <T extends AmazonWebServiceRequest> T beforeMarshalling(
-            T request) {
-
-        T local = request;
-        for (RequestHandler2 handler : requestHandler2s) {
-            local = (T) handler.beforeMarshalling(local);
-        }
-        return local;
-    }
-
-    protected ExecutionContext createExecutionContext(AmazonWebServiceRequest req) {
-        return createExecutionContext(req, signerProvider);
-    }
-
-    protected ExecutionContext createExecutionContext(AmazonWebServiceRequest req,
-                                                      SignerProvider signerProvider) {
-        boolean isMetricsEnabled = isRequestMetricsEnabled(req) || isProfilingEnabled();
-        return ExecutionContext.builder()
-                .withRequestHandler2s(requestHandler2s)
-                .withUseRequestMetrics(isMetricsEnabled)
-                .withAwsClient(this)
-                .withSignerProvider(signerProvider).build();
-    }
-
-    protected final ExecutionContext createExecutionContext(Request<?> req) {
-        return createExecutionContext(req.getOriginalRequest());
-    }
-
-    protected SignerProvider createSignerProvider(Signer signer) {
-        return new DefaultSignerProvider(this, signer);
-    }
-
-    /* Check the profiling system property and return true if set */
-    protected static boolean isProfilingEnabled() {
-        return System.getProperty(PROFILING_SYSTEM_PROPERTY) != null;
-    }
-
-    /**
-     * Returns true if request metric collection is applicable to the given
-     * request; false otherwise.
-     */
-    protected final boolean isRequestMetricsEnabled(AmazonWebServiceRequest req) {
-        RequestMetricCollector c = req.getRequestMetricCollector(); // request level collector
-        if (c != null && c.isEnabled()) {
-            return true;
-        }
-        return isRMCEnabledAtClientOrSdkLevel();
-    }
-
-    /**
-     * Returns true if request metric collection is enabled at the service
-     * client or AWS SDK level request; false otherwise.
-     */
-    private boolean isRMCEnabledAtClientOrSdkLevel() {
-        RequestMetricCollector c = requestMetricCollector();
-        return c != null && c.isEnabled();
-    }
-
-    /**
-     * Sets the optional value for time offset for this client.  This
-     * value will be applied to all requests processed through this client.
-     * Value is in seconds, positive values imply the current clock is "fast",
-     * negative values imply clock is slow.
-     *
-     * @param timeOffset
-     *            The optional value for time offset (in seconds) for this client.
-     */
-    public void setTimeOffset(int timeOffset) {
-        checkMutability();
-        this.timeOffset = timeOffset;
-    }
-
-    /**
-     * Sets the optional value for time offset for this client.  This
-     * value will be applied to all requests processed through this client.
-     * Value is in seconds, positive values imply the current clock is "fast",
-     * negative values imply clock is slow.
-     *
-     * @param timeOffset
-     *            The optional value for time offset (in seconds) for this client.
-     *
-     * @return the updated web service client
-     */
-    public AmazonWebServiceClient withTimeOffset(int timeOffset) {
-        checkMutability();
-        setTimeOffset(timeOffset);
-        return this;
-    }
-
-    /**
-     * Returns the optional value for time offset for this client.  This
-     * value will be applied to all requests processed through this client.
-     * Value is in seconds, positive values imply the current clock is "fast",
-     * negative values imply clock is slow.
-     *
-     * @return The optional value for time offset (in seconds) for this client.
-     */
-    public int getTimeOffset() {
-        return timeOffset;
-    }
-
-    /**
-     * Returns the client specific {@link RequestMetricCollector}; or null if
-     * there is none.
-     */
-    public RequestMetricCollector getRequestMetricsCollector() {
-        return client.getRequestMetricCollector();
-    }
-
-    /**
-     * Returns the client specific request metric collector if there is one; or
-     * the one at the AWS SDK level otherwise.
-     */
-    protected RequestMetricCollector requestMetricCollector() {
-        RequestMetricCollector mc = client.getRequestMetricCollector();
-        return mc == null ? AwsSdkMetrics.getRequestMetricCollector() : mc;
-    }
-
-    /**
-     * Returns the most specific request metric collector, starting from the request level, then
-     * client level, then finally the AWS SDK level.
-     */
-    private final RequestMetricCollector findRequestMetricCollector(
-            RequestMetricCollector reqLevelMetricsCollector) {
-        if (reqLevelMetricsCollector != null) {
-            return reqLevelMetricsCollector;
-        } else if (getRequestMetricsCollector() != null) {
-            return getRequestMetricsCollector();
-        } else {
-            return AwsSdkMetrics.getRequestMetricCollector();
-        }
-    }
-
-    /**
-     * Notify request handlers that we are about to start execution.
-     */
-    protected final <T extends AmazonWebServiceRequest> T beforeClientExecution(T request) {
-        T local = request;
-        for (RequestHandler2 handler : requestHandler2s) {
-            local = (T) handler.beforeExecution(local);
-        }
-        return local;
-    }
-
-    /**
-     * Convenient method to end the client execution without logging the
-     * awsRequestMetrics.
-     */
-    protected final void endClientExecution(
-            AWSRequestMetrics awsRequestMetrics, Request<?> request,
-            Response<?> response) {
-        this.endClientExecution(awsRequestMetrics, request, response,
-                !LOGGING_AWS_REQUEST_METRIC);
-    }
-
-    /**
-     * Common routine to end a client AWS request/response execution and collect
-     * the request metrics.  Caller of this routine is responsible for starting
-     * the event for {@link Field#ClientExecuteTime} and call this method
-     * in a try-finally block.
-     *
-     * @param loggingAwsRequestMetrics deprecated and ignored
-     */
-    protected final void endClientExecution(
-            AWSRequestMetrics awsRequestMetrics, Request<?> request,
-            Response<?> response, @Deprecated boolean loggingAwsRequestMetrics) {
-        if (request != null) {
-            awsRequestMetrics.endEvent(Field.ClientExecuteTime);
-            awsRequestMetrics.getTimingInfo().endTiming();
-            RequestMetricCollector c = findRequestMetricCollector(
-                    request.getOriginalRequest().getRequestMetricCollector());
-            c.collectMetrics(request, response);
-            awsRequestMetrics.log();
-        }
-    }
-
-    /**
-     * @deprecated by {@link #getServiceName()}.
-     */
-    @Deprecated
-    protected String getServiceAbbreviation() {
-        return getServiceNameIntern();
-    }
-
-    /**
-     * Returns the service abbreviation for this service, used for identifying
-     * service endpoints by region, identifying the necessary signer, etc.
-     * Used to be call "getServiceAbbreviation".
-     */
-    public String getServiceName() {
-        return getServiceNameIntern();
-    }
-
-    /**
-     * @return the service name that should be used when computing the region
-     *         endpoints. This method returns the value of the
-     *         regionMetadataServiceName configuration in the internal config
-     *         file if such configuration is specified for the current client,
-     *         otherwise it returns the same service name that is used for
-     *         request signing.
-     */
-    public String getEndpointPrefix() {
-        if (endpointPrefix != null) {
-            return endpointPrefix;
-        }
-
-        String httpClientName = getHttpClientName();
-        String serviceNameInRegionMetadata = ServiceNameFactory.
-                getServiceNameInRegionMetadata(httpClientName);
-
-        synchronized (this) {
-            if (endpointPrefix != null) {
-                return endpointPrefix;
-            }
-            if (serviceNameInRegionMetadata != null) {
-                return endpointPrefix = serviceNameInRegionMetadata;
-            } else {
-                return endpointPrefix = getServiceNameIntern();
-            }
-        }
-    }
-
-    /**
-     * @return The region used to sign requests with AWS SigV4 auth.
-     */
-    @SdkProtectedApi
-    protected String getSigningRegion() {
-        return this.signingRegion;
-    }
-
-    /**
-     * An internal method used to explicitly override the service name for region metadata.
-     * This service name is used to compute the region endpoints.
-     */
-    protected void setEndpointPrefix(String endpointPrefix) {
-        if (endpointPrefix == null) {
-            throw new IllegalArgumentException(
-                    "The parameter endpointPrefix must be specified!");
-        }
-        this.endpointPrefix = endpointPrefix;
-    }
-
-    /**
-     * Internal method for implementing {@link #getServiceName()}. Method is
-     * protected by intent so peculiar subclass that don't follow the class
-     * naming convention can choose to return whatever service name as needed.
-     */
-    protected String getServiceNameIntern() {
-        if (serviceName == null) {
-            synchronized (this) {
-                if (serviceName == null) {
-                    return serviceName = computeServiceName();
-                }
-            }
-        }
-        return serviceName;
-    }
-
-    /**
-     * An internal method used to explicitly override the service name
-     * computed by the default implementation. This method is not expected to be
-     * normally called except for AWS internal development purposes.
-     */
-    public final void setServiceNameIntern(String serviceName) {
-        if (serviceName == null)
-            throw new IllegalArgumentException(
-                    "The parameter serviceName must be specified!");
-        this.serviceName = serviceName;
-    }
-
-    /**
-     * Returns the service name of this AWS http client by first looking it up from the SDK internal
-     * configuration, and if not found, derive it from the class name of the immediate subclass of
-     * {@link AmazonWebServiceClient}. No configuration is necessary if the simple class name of the
-     * http client follows the convention of <code>(Amazon|AWS).*(JavaClient|Client)</code>.
-     */
-    private String computeServiceName() {
-        final String httpClientName = getHttpClientName();
-        String service = ServiceNameFactory.getServiceName(httpClientName);
-        if (service != null) {
-            return service; // only if it is so explicitly configured
-        }
-        // Otherwise, make use of convention over configuration
-        int j = httpClientName.indexOf("JavaClient");
-        if (j == -1) {
-            j = httpClientName.indexOf("Client");
-            if (j == -1) {
-                throw new IllegalStateException(
-                        "Unrecognized suffix for the AWS http client class name " + httpClientName);
-            }
-        }
-        int i = httpClientName.indexOf(AMAZON);
-        int len;
-        if (i == -1) {
-            i = httpClientName.indexOf(AWS);
-            if (i == -1) {
-                throw new IllegalStateException(
-                        "Unrecognized prefix for the AWS http client class name " + httpClientName);
-            }
-            len = AWS.length();
-        } else {
-            len = AMAZON.length();
-        }
-        if (i >= j) {
-            throw new IllegalStateException(
-                    "Unrecognized AWS http client class name " + httpClientName);
-        }
-        String serviceName = httpClientName.substring(i + len, j);
-        return StringUtils.lowerCase(serviceName);
-    }
-
-    private String getHttpClientName() {
-        Class<?> httpClientClass = Classes.childClassOf(AmazonWebServiceClient.class, this);
-        return httpClientClass.getSimpleName();
-    }
-
-    /**
-     * Returns the signer region override.
-     *
-     * @see #setSignerRegionOverride(String).
-     */
-    public final String getSignerRegionOverride() {
-        return signerRegionOverride;
-    }
-
-    /**
-     * An internal method used to explicitly override the internal signer region
-     * computed by the default implementation. This method is not expected to be
-     * normally called except for AWS internal development purposes.
-     */
-    public final void setSignerRegionOverride(String signerRegionOverride) {
-        checkMutability();
-        Signer signer = computeSignerByURI(endpoint, signerRegionOverride, true);
-        synchronized(this)  {
-            this.signerRegionOverride = signerRegionOverride;
-            this.signerProvider = createSignerProvider(signer);
-            this.signingRegion = signerRegionOverride;
-        }
-    }
-
-    /**
-     * Fluent method for {@link #setRegion(Region)}.
-     *<pre>
-     * Example:
-     *
-     *   AmazonDynamoDBClient client = new AmazonDynamoDBClient(...).<AmazonDynamoDBClient>withRegion(...);
-     *</pre>
-     * @see #setRegion(Region)
-     * @deprecated use {@link AwsClientBuilder#withRegion(Region)} for example:
-     * {@code AmazonSNSClientBuilder.standard().withRegion(region).build();}
-     */
-    @Deprecated
-    public <T extends AmazonWebServiceClient> T withRegion(Region region) {
-        setRegion(region);
-        @SuppressWarnings("unchecked") T t= (T)this;
-        return t;
-    }
-
-    /**
-     * Convenient fluent method for setting region.
-     *
-     * @param region region to set to; must not be null.
-     *
-     * @see #withRegion(Region)
-     * @deprecated use {@link AwsClientBuilder#withRegion(Regions)} for example:
-     * {@code AmazonSNSClientBuilder.standard().withRegion(region).build();}
-     */
-    @Deprecated
-    public <T extends AmazonWebServiceClient> T withRegion(Regions region) {
-        configureRegion(region);
-        @SuppressWarnings("unchecked") T t= (T)this;
-        return t;
-    }
-    /**
-     * Fluent method for {@link #setEndpoint(String)}.
-     *<pre>
-     * Example:
-     *
-     *   AmazonDynamoDBClient client = new AmazonDynamoDBClient(...).<AmazonDynamoDBClient>withEndPoint(...);
-     *</pre>
-     * @see #setEndpoint(String)
-     * @deprecated use {@link AwsClientBuilder#withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration)} for example:
-     * {@code AmazonSNSClientBuilder.standard().withEndpointConfiguration(new EndpointConfiguration(endpoint, signingRegion)).build();}
-     */
-    @Deprecated
-    public <T extends AmazonWebServiceClient> T withEndpoint(String endpoint) {
-        setEndpoint(endpoint);
-        @SuppressWarnings("unchecked") T t= (T)this;
-        return t;
-    }
-
-    /**
-     * Internal only API to lock a client's mutable methods. Only intended for use by the fluent
-     * builders.
-     */
-    @Deprecated
-    @SdkInternalApi
-    public final void makeImmutable() {
-        this.isImmutable = true;
-    }
-
-    /**
-     * If the client has been marked as immutable then throw an {@link
-     * UnsupportedOperationException}, otherwise do nothing. Should be called by each mutating
-     * method.
-     */
-    @SdkProtectedApi
-    protected final void checkMutability() {
-        if (isImmutable) {
-            throw new UnsupportedOperationException(
-                    "Client is immutable when created with the builder.");
-        }
-    }
-
-    /**
-     * Hook to allow S3 client to disable strict hostname verification since it uses wildcard
-     * certificates.
-     *
-     * @return True if strict hostname verification should be used, false otherwise.
-     */
-    protected boolean useStrictHostNameVerification() {
-        return true;
-    }
-
-    /**
-     * Hook to allow clients to override CRC32 calculation behavior. Currently, only exercised by DynamoDB.
-     *
-     * @return True if the service returns CRC32 checksum from the compressed data, false otherwise.
-     */
-    protected boolean calculateCRC32FromCompressedData() {
-        return false;
-    }
-
-    public String getSignerOverride() {
-        return clientConfiguration.getSignerOverride();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/AmazonWebServiceRequest.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceRequest.java
--- ./src/main/java/com/amazonaws/AmazonWebServiceRequest.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceRequest.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,601 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.event.ProgressListener;
-import com.amazonaws.handlers.HandlerContextKey;
-import com.amazonaws.internal.StaticCredentialsProvider;
-import com.amazonaws.metrics.RequestMetricCollector;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Base class for all user facing web service requests.
- */
-@NotThreadSafe
-public abstract class AmazonWebServiceRequest implements Cloneable, ReadLimitInfo, HandlerContextAware {
-
-    public static final AmazonWebServiceRequest NOOP = new AmazonWebServiceRequest() {
-    };
-
-    /**
-     * The optional progress listener for receiving updates about the progress of the request.
-     */
-    private ProgressListener progressListener = ProgressListener.NOOP;
-
-    /**
-     * Arbitrary options storage for individual {@link AmazonWebServiceRequest}s. This field is not
-     * intended to be used by clients.
-     */
-    private final RequestClientOptions requestClientOptions = new RequestClientOptions();
-
-    /**
-     * A request metric collector used for this specific service request; or null if there is none.
-     * This collector always takes precedence over the ones specified at the http client level and
-     * AWS SDK level.
-     */
-    private RequestMetricCollector requestMetricCollector;
-
-    /**
-     * The optional credentials to use for this request - overrides the default credentials set at
-     * the client level.
-     */
-    private AWSCredentialsProvider credentialsProvider;
-
-    /**
-     * A map of custom header names to header values.
-     */
-    private Map<String, String> customRequestHeaders;
-
-    /**
-     * Custom query parameters for the request.
-     */
-    private Map<String, List<String>> customQueryParameters;
-
-    /**
-     * User-defined context for the request.
-     */
-    private transient Map<HandlerContextKey<?>, Object> handlerContext = new HashMap<HandlerContextKey<?>, Object>();
-
-    /**
-     * The source object from which the current object was cloned; or null if there isn't one.
-     */
-    private AmazonWebServiceRequest cloneSource;
-
-    private Integer sdkRequestTimeout = null;
-
-    private Integer sdkClientExecutionTimeout = null;
-
-    /**
-     * Sets the optional credentials to use for this request, overriding the default credentials set at the client level.
-     *
-     * @param credentials The optional AWS security credentials to use for this request, overriding the default credentials set at
-     *                    the client level.
-     * @deprecated by {@link #setRequestCredentialsProvider(AWSCredentialsProvider)}. If you must use {@link AWSCredentials} you
-     * can wrap it with a {@link com.amazonaws.auth.AWSStaticCredentialsProvider}.
-     */
-    @Deprecated
-    public void setRequestCredentials(AWSCredentials credentials) {
-        this.credentialsProvider = credentials == null ? null : new StaticCredentialsProvider(credentials);
-    }
-
-    /**
-     * Returns the optional credentials to use to sign this request, overriding the default
-     * credentials set at the client level.
-     *
-     * @return The optional credentials to use to sign this request, overriding the default
-     *         credentials set at the client level.
-     *
-     * @deprecated by {@link #getRequestCredentialsProvider()}
-     */
-    @Deprecated
-    public AWSCredentials getRequestCredentials() {
-        return credentialsProvider == null ? null : credentialsProvider.getCredentials();
-    }
-
-    /**
-     * Sets the optional credentials provider to use for this request, overriding the default credentials
-     * provider at the client level.
-     *
-     * @param credentialsProvider
-     *            The optional AWS security credentials provider to use for this request, overriding the
-     *            default credentials provider at the client level.
-     */
-    public void setRequestCredentialsProvider(AWSCredentialsProvider credentialsProvider) {
-        this.credentialsProvider = credentialsProvider;
-    }
-
-    /**
-     * Returns the optional credentials provider to use to sign this request, overriding the default
-     * credentials provider at the client level.
-     *
-     * @return The optional credentials provider to use to sign this request, overriding the default
-     *         credentials provider at the client level.
-     */
-    public AWSCredentialsProvider getRequestCredentialsProvider() {
-        return credentialsProvider;
-    }
-
-    /**
-     * Sets the optional credentials provider to use for this request, overriding the default credentials
-     * provider at the client level.
-     *
-     * @param credentialsProvider
-     *            The optional AWS security credentials provider to use for this request, overriding the
-     *            default credentials provider at the client level.
-     * @return A reference to this updated object so that method calls can be chained together.
-     */
-    public <T extends AmazonWebServiceRequest> T withRequestCredentialsProvider(final AWSCredentialsProvider credentialsProvider) {
-        setRequestCredentialsProvider(credentialsProvider);
-        @SuppressWarnings("unchecked")
-        T t = (T) this;
-        return t;
-    }
-
-    /**
-     * Gets the options stored with this request object. Intended for internal use only.
-     */
-    public RequestClientOptions getRequestClientOptions() {
-        return requestClientOptions;
-    }
-
-    /**
-     * Returns a request level metric collector; or null if not specified.
-     */
-    public RequestMetricCollector getRequestMetricCollector() {
-        return requestMetricCollector;
-    }
-
-    /**
-     * Sets a request level request metric collector which takes precedence over the ones at the
-     * http client level and AWS SDK level.
-     */
-    public void setRequestMetricCollector(RequestMetricCollector requestMetricCollector) {
-        this.requestMetricCollector = requestMetricCollector;
-    }
-
-    /**
-     * Specifies a request level metric collector which takes precedence over the ones at the http
-     * client level and AWS SDK level.
-     */
-    public <T extends AmazonWebServiceRequest> T withRequestMetricCollector(RequestMetricCollector metricCollector) {
-        setRequestMetricCollector(metricCollector);
-        @SuppressWarnings("unchecked")
-        T t = (T) this;
-        return t;
-    }
-
-    /**
-     * Sets the optional progress listener for receiving updates about the progress of the request.
-     *
-     * @param progressListener
-     *            The new progress listener.
-     */
-    public void setGeneralProgressListener(ProgressListener progressListener) {
-        this.progressListener = progressListener == null ? ProgressListener.NOOP : progressListener;
-    }
-
-    /**
-     * Returns the optional progress listener for receiving updates about the progress of the
-     * request.
-     *
-     * @return the optional progress listener for receiving updates about the progress of the
-     *         request.
-     */
-    public ProgressListener getGeneralProgressListener() {
-        return progressListener;
-    }
-
-    /**
-     * Sets the optional progress listener for receiving updates about the progress of the request,
-     * and returns a reference to this object so that method calls can be chained together.
-     *
-     * @param progressListener
-     *            The new progress listener.
-     * @return A reference to this updated object so that method calls can be chained together.
-     */
-    public <T extends AmazonWebServiceRequest> T withGeneralProgressListener(ProgressListener progressListener) {
-        setGeneralProgressListener(progressListener);
-        @SuppressWarnings("unchecked")
-        T t = (T) this;
-        return t;
-    }
-
-    /**
-     * Returns an immutable map of custom header names to header values.
-     *
-     * @return The immutable map of custom header names to header values.
-     */
-    public Map<String, String> getCustomRequestHeaders() {
-        if (customRequestHeaders == null) {
-            return null;
-        }
-        return Collections.unmodifiableMap(customRequestHeaders);
-    }
-
-    /**
-     * Put a new custom header to the map of custom header names to custom header values, and return
-     * the previous value if the header has already been set in this map.
-     * <p>
-     * Any custom headers that are defined are used in the HTTP request to the AWS service. These
-     * headers will be silently ignored in the event that AWS does not recognize them.
-     * <p>
-     * NOTE: Custom header values set via this method will overwrite any conflicting values coming
-     * from the request parameters.
-     *
-     * @param name
-     *            The name of the header to add
-     * @param value
-     *            The value of the header to add
-     * @return the previous value for the name if it was set, null otherwise
-     */
-    public String putCustomRequestHeader(String name, String value) {
-        if (customRequestHeaders == null) {
-            customRequestHeaders = new HashMap<String, String>();
-        }
-        return customRequestHeaders.put(name, value);
-    }
-
-    /**
-     * @return the immutable map of custom query parameters. The parameter value is modeled as a
-     *         list of strings because multiple values can be specified for the same parameter name.
-     */
-    public Map<String, List<String>> getCustomQueryParameters() {
-        if (customQueryParameters == null) {
-            return null;
-        }
-        return Collections.unmodifiableMap(customQueryParameters);
-    }
-
-    /**
-     * Add a custom query parameter for the request. Since multiple values are allowed for the same
-     * query parameter, this method does NOT overwrite any existing parameter values in the request.
-     * <p>
-     * Any custom query parameters that are defined are used in the HTTP request to the AWS service.
-     *
-     * @param name
-     *            The name of the query parameter
-     * @param value
-     *            The value of the query parameter. Only the parameter name will be added in the URI
-     *            if the value is set to null. For example, putCustomQueryParameter("param", null)
-     *            will be serialized to "?param", while putCustomQueryParameter("param", "") will be
-     *            serialized to "?param=".
-     */
-    public void putCustomQueryParameter(String name, String value) {
-        if (customQueryParameters == null) {
-            customQueryParameters = new HashMap<String, List<String>>();
-        }
-        List<String> paramList = customQueryParameters.get(name);
-        if (paramList == null) {
-            paramList = new LinkedList<String>();
-            customQueryParameters.put(name, paramList);
-        }
-        paramList.add(value);
-    }
-
-    @Override
-    public final int getReadLimit() {
-        return requestClientOptions.getReadLimit();
-    }
-
-    /**
-     * Copies the internal state of this base class to that of the target request.
-     *
-     * @return the target request
-     */
-    protected final <T extends AmazonWebServiceRequest> T copyBaseTo(T target) {
-        if (customRequestHeaders != null) {
-            for (Map.Entry<String, String> e : customRequestHeaders.entrySet())
-                target.putCustomRequestHeader(e.getKey(), e.getValue());
-        }
-        if (customQueryParameters != null) {
-            for (Map.Entry<String, List<String>> e : customQueryParameters.entrySet()) {
-                if (e.getValue() != null) {
-                    for (String value : e.getValue()) {
-                        target.putCustomQueryParameter(e.getKey(), value);
-                    }
-                }
-            }
-        }
-
-        target.setRequestCredentialsProvider(credentialsProvider);
-        target.setGeneralProgressListener(progressListener);
-        target.setRequestMetricCollector(requestMetricCollector);
-        requestClientOptions.copyTo(target.getRequestClientOptions());
-        return target;
-    }
-
-    /**
-     * Returns the source object from which the current object was cloned; or null if there isn't
-     * one.
-     */
-    public AmazonWebServiceRequest getCloneSource() {
-        return cloneSource;
-    }
-
-    /**
-     * Returns the root object from which the current object was cloned; or null if there isn't one.
-     */
-    public AmazonWebServiceRequest getCloneRoot() {
-        AmazonWebServiceRequest cloneRoot = cloneSource;
-        if (cloneRoot != null) {
-            while (cloneRoot.getCloneSource() != null) {
-                cloneRoot = cloneRoot.getCloneSource();
-            }
-        }
-        return cloneRoot;
-    }
-
-    private void setCloneSource(AmazonWebServiceRequest cloneSource) {
-        this.cloneSource = cloneSource;
-    }
-
-    /**
-     * Returns the amount of time to wait (in milliseconds) for the request to complete before
-     * giving up and timing out. A non-positive value disables this feature.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The request timeout feature doesn't have strict guarantees on how quickly a request is
-     * aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this the request timeout feature should
-     * not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @return The amount of time to wait (in milliseconds) for the request to complete before
-     *         giving up and timing out. A non-positive value disables the timeout for this request.
-     * @see {@link AmazonWebServiceRequest#setSdkClientExecutionTimeout(int)} to enforce a timeout
-     *      across all retries
-     */
-    public Integer getSdkRequestTimeout() {
-        return sdkRequestTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) for the request to complete before giving
-     * up and timing out. A non-positive value disables this feature.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The request timeout feature doesn't have strict guarantees on how quickly a request is
-     * aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this the request timeout feature should
-     * not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param sdkRequestTimeout
-     *            The amount of time to wait (in milliseconds) for the request to complete before
-     *            giving up and timing out. A non-positive value disables the timeout for this
-     *            request.
-     * @see {@link AmazonWebServiceRequest#setSdkClientExecutionTimeout(int)} to enforce a timeout
-     *      across all retries
-     */
-    public void setSdkRequestTimeout(int sdkRequestTimeout) {
-        this.sdkRequestTimeout = sdkRequestTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) for the request to complete before giving
-     * up and timing out. A non-positive value disables this feature. Returns the updated
-     * AmazonWebServiceRequest object so that additional method calls may be chained together.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The request timeout feature doesn't have strict guarantees on how quickly a request is
-     * aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this the request timeout feature should
-     * not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param sdkRequestTimeout
-     *            The amount of time to wait (in milliseconds) for the request to complete before
-     *            giving up and timing out. A non-positive value disables the timeout for this
-     *            request.
-     * @return The updated {@link AmazonWebServiceRequest} object.
-     * @see {@link AmazonWebServiceRequest#setSdkClientExecutionTimeout(int)} to enforce a timeout
-     *      across all retries
-     */
-    public <T extends AmazonWebServiceRequest> T withSdkRequestTimeout(int sdkRequestTimeout) {
-        setSdkRequestTimeout(sdkRequestTimeout);
-        @SuppressWarnings("unchecked")
-        T t = (T) this;
-        return t;
-    }
-
-    /**
-     * Returns the amount of time (in milliseconds) to allow the client to complete the execution of
-     * an API call. This timeout covers the entire client execution except for marshalling. This
-     * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The client execution timeout feature doesn't have strict guarantees on how quickly a request
-     * is aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this the client execution timeout
-     * feature should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * This may be used together with {@link AmazonWebServiceRequest#setSdkRequestTimeout(int)} to
-     * enforce both a timeout on each individual HTTP request (i.e. each retry) and the total time
-     * spent on all requests across retries (i.e. the 'client execution' time). A non-positive value
-     * disables this feature.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @return The amount of time (in milliseconds) to allow the client to complete the execution of
-     *         an API call. A non-positive value disables the timeout for this request.
-     * @see {@link AmazonWebServiceRequest#setSdkRequestTimeout(int)} to enforce a timeout per HTTP
-     *      request
-     */
-    public Integer getSdkClientExecutionTimeout() {
-        return this.sdkClientExecutionTimeout;
-    }
-
-    /**
-     * Sets the amount of time (in milliseconds) to allow the client to complete the execution of
-     * an API call. This timeout covers the entire client execution except for marshalling. This
-     * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The client execution timeout feature doesn't have strict guarantees on how quickly a request
-     * is aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this the client execution timeout
-     * feature should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * This may be used together with {@link AmazonWebServiceRequest#setSdkRequestTimeout(int)} to
-     * enforce both a timeout on each individual HTTP request (i.e. each retry) and the total time
-     * spent on all requests across retries (i.e. the 'client execution' time). A non-positive value
-     * disables this feature.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param sdkClientExecutionTimeout
-     *            The amount of time (in milliseconds) to allow the client to complete the execution
-     *            of an API call. A non-positive value disables the timeout for this request.
-     * @see {@link AmazonWebServiceRequest#setSdkRequestTimeout(int)} to enforce a timeout per HTTP
-     *      request
-     */
-    public void setSdkClientExecutionTimeout(int sdkClientExecutionTimeout) {
-        this.sdkClientExecutionTimeout = sdkClientExecutionTimeout;
-    }
-
-    /**
-     * Sets the amount of time (in milliseconds) to allow the client to complete the execution of
-     * an API call. This timeout covers the entire client execution except for marshalling. This
-     * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The client execution timeout feature doesn't have strict guarantees on how quickly a request
-     * is aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this the client execution timeout
-     * feature should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * This may be used together with {@link AmazonWebServiceRequest#setSdkRequestTimeout(int)} to
-     * enforce both a timeout on each individual HTTP request (i.e. each retry) and the total time
-     * spent on all requests across retries (i.e. the 'client execution' time). A non-positive value
-     * disables this feature.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param sdkClientExecutionTimeout
-     *            The amount of time (in milliseconds) to allow the client to complete the execution
-     *            of an API call. A non-positive value disables the timeout for this request.
-     * @return The updated AmazonWebServiceRequest object for method chaining
-     * @see {@link AmazonWebServiceRequest#setSdkRequestTimeout(int)} to enforce a timeout per HTTP
-     *      request
-     */
-    public <T extends AmazonWebServiceRequest> T withSdkClientExecutionTimeout(int sdkClientExecutionTimeout) {
-        setSdkClientExecutionTimeout(sdkClientExecutionTimeout);
-        @SuppressWarnings("unchecked")
-        T t = (T) this;
-        return t;
-    }
-
-    @Override
-    public <X> void addHandlerContext(HandlerContextKey<X> key, X value) {
-        this.handlerContext.put(key, value);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <X> X getHandlerContext(HandlerContextKey<X> key) {
-        return (X) this.handlerContext.get(key);
-    }
-
-    /**
-     * Retrieve an unmodifiable collection of all handler context objects. This allows a {@link Request} derived from a
-     * {@link AmazonWebServiceRequest} to inherit its context. This does not protect the objects within the map from being
-     * modified.
-     *
-     * <p>This should not be used by customers.</p>
-     */
-    @SdkInternalApi
-    Map<HandlerContextKey<?>, Object> getHandlerContext() {
-        return Collections.unmodifiableMap(this.handlerContext);
-    }
-
-    /**
-     * Creates a shallow clone of this object for all fields except the handler context. Explicitly does <em>not</em> clone the
-     * deep structure of the other fields in the message.
-     *
-     * @see Object#clone()
-     */
-    @Override
-    public AmazonWebServiceRequest clone() {
-        try {
-            AmazonWebServiceRequest cloned = (AmazonWebServiceRequest) super.clone();
-            cloned.setCloneSource(this);
-
-            // Deep-copy context to ensure modifications made by the handlers do not leak back to the caller or other uses of the
-            // same request.
-            cloned.handlerContext = new HashMap<HandlerContextKey<?>, Object>(cloned.handlerContext);
-
-            return cloned;
-        } catch (CloneNotSupportedException e) {
-            throw new IllegalStateException(
-                    "Got a CloneNotSupportedException from Object.clone() " + "even though we're Cloneable!", e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/AmazonWebServiceResponse.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceResponse.java
--- ./src/main/java/com/amazonaws/AmazonWebServiceResponse.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceResponse.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,88 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-/**
- * Represents the response from an AWS service, including the result payload and
- * any response metadata. AWS response metadata consists primarily of the AWS
- * request ID, which can be used for debugging purposes when services aren't
- * acting as expected.
- *
- * @param <T>
- *            The type of result contained by this response.
- */
-public class AmazonWebServiceResponse<T> {
-
-    /** The result contained by this response */
-    private T result;
-
-    /** Additional AWS metadata for this response */
-    private ResponseMetadata responseMetadata;
-
-    /**
-     * Returns the result contained by this response.
-     *
-     * @return The result contained by this response.
-     */
-    public T getResult() {
-        return result;
-    }
-
-    /**
-     * Sets the result contained by this response.
-     *
-     * @param result
-     *            The result contained by this response.
-     */
-    public void setResult(T result) {
-        this.result = result;
-    }
-
-    /**
-     * Sets the response metadata associated with this response.
-     * 
-     * @param responseMetadata
-     *            The response metadata for this response.
-     */
-    public void setResponseMetadata(ResponseMetadata responseMetadata) {
-        this.responseMetadata = responseMetadata;
-    }
-
-    /**
-     * Returns the response metadata for this response. Response metadata
-     * provides additional information about a response that isn't necessarily
-     * directly part of the data the service is returning. Response metadata is
-     * primarily used for debugging issues with AWS support when a service isn't
-     * working as expected.
-     * 
-     * @return The response metadata for this response.
-     */
-    public ResponseMetadata getResponseMetadata() {
-        return responseMetadata;
-    }
-
-    /**
-     * Returns the AWS request ID from the response metadata section of an AWS
-     * response.
-     *
-     * @return The AWS request ID from the response metadata section of an AWS
-     *         response.
-     */
-    public String getRequestId() {
-        if (responseMetadata == null) return null;
-        return responseMetadata.getRequestId();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/AmazonWebServiceResult.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceResult.java
--- ./src/main/java/com/amazonaws/AmazonWebServiceResult.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AmazonWebServiceResult.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.http.SdkHttpMetadata;
-
-/**
- * Base type for all AWS response objects. Exposes metadata about the request such as the request
- * id and access to details in the HTTP response.
- *
- * @param <T> Type of {@link ResponseMetadata}.
- */
-public class AmazonWebServiceResult<T extends ResponseMetadata> {
-
-    private T sdkResponseMetadata;
-
-    private SdkHttpMetadata sdkHttpMetadata;
-
-    /**
-     * @return The response metadata associated with this request.
-     */
-    public T getSdkResponseMetadata() {
-        return sdkResponseMetadata;
-    }
-
-    public AmazonWebServiceResult<T> setSdkResponseMetadata(T sdkResponseMetadata) {
-        this.sdkResponseMetadata = sdkResponseMetadata;
-        return this;
-    }
-
-    /**
-     * @return HTTP related metadata like headers and status code.
-     */
-    public SdkHttpMetadata getSdkHttpMetadata() {
-        return sdkHttpMetadata;
-    }
-
-    public AmazonWebServiceResult<T> setSdkHttpMetadata(SdkHttpMetadata sdkHttpMetadata) {
-        this.sdkHttpMetadata = sdkHttpMetadata;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/annotation/Beta.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/Beta.java
--- ./src/main/java/com/amazonaws/annotation/Beta.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/Beta.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
- * the License. A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- */
-package com.amazonaws.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * The class or method to which this annotation is applied is in beta mode. This
- * means the annotated class or method is a relatively new API that may have
- * bugs, complexity and usability issues that we have not fully anticipated. We
- * will remove this annotation from the class or method once things get more
- * settled.
- */
-@Documented
-@Target({ ElementType.TYPE, ElementType.METHOD })
-@Retention(RetentionPolicy.CLASS)
-public @interface Beta {
-}
diff -Nau8r ./src/main/java/com/amazonaws/annotation/GuardedBy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/GuardedBy.java
--- ./src/main/java/com/amazonaws/annotation/GuardedBy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/GuardedBy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
- * the License. A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- */
-package com.amazonaws.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Documenting annotation to indicate the field or method on which this is applied can only be accessed
- * when holding the given lock (identified by value).
- */
-@Documented
-@Target({ElementType.FIELD, ElementType.METHOD})
-@Retention(RetentionPolicy.CLASS)
-public @interface GuardedBy {
-    String value();
-}
diff -Nau8r ./src/main/java/com/amazonaws/annotation/NotThreadSafe.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/NotThreadSafe.java
--- ./src/main/java/com/amazonaws/annotation/NotThreadSafe.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/NotThreadSafe.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
- * the License. A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- */
-package com.amazonaws.annotation;
-
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Documenting annotation to indicate a class is not thread-safe and should not be used in a multi-threaded context.
- *
- * @see ThreadSafe
- */
-@Documented
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.CLASS)
-public @interface NotThreadSafe {
-}
diff -Nau8r ./src/main/java/com/amazonaws/annotation/SdkTestInternalApi.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkTestInternalApi.java
--- ./src/main/java/com/amazonaws/annotation/SdkTestInternalApi.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/annotation/SdkTestInternalApi.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
- * the License. A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- */
-package com.amazonaws.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-
-/**
- * Marker interface for methods used by test code in the same module. Methods/Constructors annotated
- * with this method should not be accessed in production code. This annotation should be used
- * sparingly as it's a code smell to need access to internal data/functionality to properly unit
- * test a class. Typically there is a better way to test a class.
- * <p>
- * TODO: Write a linter that makes sure only test code depends on methods or constructors annotated
- * with this method
- */
-@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD })
-public @interface SdkTestInternalApi {
-}
diff -Nau8r ./src/main/java/com/amazonaws/ApacheHttpClientConfig.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ApacheHttpClientConfig.java
--- ./src/main/java/com/amazonaws/ApacheHttpClientConfig.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ApacheHttpClientConfig.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,64 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.NotThreadSafe;
-
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-
-/**
- * Used for Apache HTTP client specific custom configurations.
- */
-@NotThreadSafe
-public final class ApacheHttpClientConfig {
-    private ConnectionSocketFactory sslSocketFactory;
-
-    ApacheHttpClientConfig() {}
-
-    ApacheHttpClientConfig(ApacheHttpClientConfig that) {
-        this.sslSocketFactory = that.sslSocketFactory;
-    }
-
-    /**
-     * Returns a custom Apache HTTP client specific SSL socket factory; 
-     * or null if there is none.
-     */
-    public ConnectionSocketFactory getSslSocketFactory() {
-        return sslSocketFactory;
-    }
-
-    /**
-     * Sets a custom Apache HTTP client specific SSL socket factory.
-     * 
-     * @param sslSocketFactory a custom Apache HTTP client specific SSL socket 
-     * factory; or null if there is none.
-     */
-    public void setSslSocketFactory(ConnectionSocketFactory sslSocketFactory) {
-        this.sslSocketFactory = sslSocketFactory;
-    }
-
-    /**
-     * Fluent API for setting a custom Apache HTTP client specific SSL socket
-     * factory.
-     * 
-     * @param sslSocketFactory a custom Apache HTTP client specific SSL socket 
-     * factory; or null if there is none.
-     */
-    public ApacheHttpClientConfig withSslSocketFactory(
-            ConnectionSocketFactory sslSocketFactory) {
-        this.sslSocketFactory = sslSocketFactory;
-        return this;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/auth/AbstractAWSSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AbstractAWSSigner.java
--- ./src/main/java/com/amazonaws/auth/AbstractAWSSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AbstractAWSSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,483 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import static com.amazonaws.util.StringUtils.UTF8;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.net.URI;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.*;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.ReadLimitInfo;
-import com.amazonaws.SDKGlobalTime;
-import com.amazonaws.SignableRequest;
-import com.amazonaws.internal.SdkDigestInputStream;
-import com.amazonaws.util.Base64;
-import com.amazonaws.util.BinaryUtils;
-import com.amazonaws.util.SdkHttpUtils;
-import com.amazonaws.util.StringUtils;
-
-/**
- * Abstract base class for AWS signing protocol implementations. Provides
- * utilities commonly needed by signing protocols such as computing
- * canonicalized host names, query string parameters, etc.
- * <p>
- * Not intended to be sub-classed by developers.
- */
-public abstract class AbstractAWSSigner implements Signer {
-
-    public static final String EMPTY_STRING_SHA256_HEX;
-    private static final ThreadLocal<MessageDigest> SHA256_MESSAGE_DIGEST;
-
-    static {
-        SHA256_MESSAGE_DIGEST = new ThreadLocal<MessageDigest>() {
-            @Override
-            protected MessageDigest initialValue() {
-                try {
-                    return MessageDigest.getInstance("SHA-256");
-                } catch (NoSuchAlgorithmException e) {
-                    throw new SdkClientException(
-                            "Unable to get SHA256 Function"
-                                    + e.getMessage(), e);
-                }
-            }
-        };
-        EMPTY_STRING_SHA256_HEX = BinaryUtils.toHex(doHash(""));
-    }
-
-    /**
-     * Computes an RFC 2104-compliant HMAC signature and returns the result as a
-     * Base64 encoded string.
-     */
-    protected String signAndBase64Encode(String data, String key,
-            SigningAlgorithm algorithm) throws SdkClientException {
-        return signAndBase64Encode(data.getBytes(UTF8), key, algorithm);
-    }
-
-    /**
-     * Computes an RFC 2104-compliant HMAC signature for an array of bytes and
-     * returns the result as a Base64 encoded string.
-     */
-    protected String signAndBase64Encode(byte[] data, String key,
-            SigningAlgorithm algorithm) throws SdkClientException {
-        try {
-            byte[] signature = sign(data, key.getBytes(UTF8), algorithm);
-            return Base64.encodeAsString(signature);
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to calculate a request signature: "
-                            + e.getMessage(), e);
-        }
-    }
-
-    public byte[] sign(String stringData, byte[] key,
-            SigningAlgorithm algorithm) throws SdkClientException {
-        try {
-            byte[] data = stringData.getBytes(UTF8);
-            return sign(data, key, algorithm);
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to calculate a request signature: "
-                            + e.getMessage(), e);
-        }
-    }
-
-    public byte[] signWithMac(String stringData, Mac mac) {
-        try {
-            return mac.doFinal(stringData.getBytes(UTF8));
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to calculate a request signature: "
-                            + e.getMessage(), e);
-        }
-    }
-
-    protected byte[] sign(byte[] data, byte[] key,
-            SigningAlgorithm algorithm) throws SdkClientException {
-        try {
-            Mac mac = algorithm.getMac();
-            mac.init(new SecretKeySpec(key, algorithm.toString()));
-            return mac.doFinal(data);
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to calculate a request signature: "
-                            + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Hashes the string contents (assumed to be UTF-8) using the SHA-256
-     * algorithm.
-     *
-     * @param text
-     *            The string to hash.
-     *
-     * @return The hashed bytes from the specified string.
-     *
-     * @throws SdkClientException
-     *             If the hash cannot be computed.
-     */
-    public byte[] hash(String text) throws SdkClientException {
-        return AbstractAWSSigner.doHash(text);
-    }
-
-    private static byte[] doHash(String text) throws SdkClientException {
-        try {
-            MessageDigest md = getMessageDigestInstance();
-            md.update(text.getBytes(UTF8));
-            return md.digest();
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to compute hash while signing request: "
-                            + e.getMessage(), e);
-        }
-    }
-
-    protected byte[] hash(InputStream input) throws SdkClientException {
-        try {
-            MessageDigest md = getMessageDigestInstance();
-            @SuppressWarnings("resource")
-            DigestInputStream digestInputStream = new SdkDigestInputStream(
-                    input, md);
-            byte[] buffer = new byte[1024];
-            while (digestInputStream.read(buffer) > -1)
-                ;
-            return digestInputStream.getMessageDigest().digest();
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to compute hash while signing request: "
-                            + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Hashes the binary data using the SHA-256 algorithm.
-     *
-     * @param data
-     *            The binary data to hash.
-     *
-     * @return The hashed bytes from the specified data.
-     *
-     * @throws SdkClientException
-     *             If the hash cannot be computed.
-     */
-    public byte[] hash(byte[] data) throws SdkClientException {
-        try {
-            MessageDigest md =  getMessageDigestInstance();
-            md.update(data);
-            return md.digest();
-        } catch (Exception e) {
-            throw new SdkClientException(
-                    "Unable to compute hash while signing request: "
-                            + e.getMessage(), e);
-        }
-    }
-    /**
-     * Examines the specified query string parameters and returns a
-     * canonicalized form.
-     * <p>
-     * The canonicalized query string is formed by first sorting all the query
-     * string parameters, then URI encoding both the key and value and then
-     * joining them, in order, separating key value pairs with an '&'.
-     *
-     * @param parameters
-     *            The query string parameters to be canonicalized.
-     *
-     * @return A canonicalized form for the specified query string parameters.
-     */
-    protected String getCanonicalizedQueryString(Map<String, List<String>> parameters) {
-
-        final SortedMap<String, List<String>> sorted = new TreeMap<String, List<String>>();
-
-        /**
-         * Signing protocol expects the param values also to be sorted after url
-         * encoding in addition to sorted parameter names.
-         */
-        for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
-            final String encodedParamName = SdkHttpUtils.urlEncode(
-                    entry.getKey(), false);
-            final List<String> paramValues = entry.getValue();
-            final List<String> encodedValues = new ArrayList<String>(
-                    paramValues.size());
-            for (String value : paramValues) {
-                encodedValues.add(SdkHttpUtils.urlEncode(value, false));
-            }
-            Collections.sort(encodedValues);
-            sorted.put(encodedParamName, encodedValues);
-
-        }
-
-        final StringBuilder result = new StringBuilder();
-        for(Map.Entry<String, List<String>> entry : sorted.entrySet()) {
-            for(String value : entry.getValue()) {
-                if (result.length() > 0) {
-                    result.append("&");
-                }
-                result.append(entry.getKey())
-                      .append("=")
-                      .append(value);
-            }
-        }
-
-        return result.toString();
-    }
-
-    protected String getCanonicalizedQueryString(SignableRequest<?> request) {
-        /*
-         * If we're using POST and we don't have any request payload content,
-         * then any request query parameters will be sent as the payload, and
-         * not in the actual query string.
-         */
-        if (SdkHttpUtils.usePayloadForQueryParameters(request))
-            return "";
-        return this.getCanonicalizedQueryString(request.getParameters());
-    }
-
-    /**
-     * Returns the request's payload as binary data.
-     *
-     * @param request
-     *            The request
-     * @return The data from the request's payload, as binary data.
-     */
-    protected byte[] getBinaryRequestPayload(SignableRequest<?> request) {
-        if (SdkHttpUtils.usePayloadForQueryParameters(request)) {
-            String encodedParameters = SdkHttpUtils.encodeParameters(request);
-            if (encodedParameters == null)
-                return new byte[0];
-
-            return encodedParameters.getBytes(UTF8);
-        }
-
-        return getBinaryRequestPayloadWithoutQueryParams(request);
-    }
-
-    /**
-     * Returns the request's payload as a String.
-     *
-     * @param request
-     *            The request
-     * @return The data from the request's payload, as a string.
-     */
-    protected String getRequestPayload(SignableRequest<?> request) {
-        return newString(getBinaryRequestPayload(request));
-    }
-
-    /**
-     * Returns the request's payload contents as a String, without processing
-     * any query string params (i.e. no form encoding for query params).
-     *
-     * @param request
-     *            The request
-     * @return the request's payload contents as a String, not including any
-     *         form encoding of query string params.
-     */
-    protected String getRequestPayloadWithoutQueryParams(SignableRequest<?> request) {
-        return newString(getBinaryRequestPayloadWithoutQueryParams(request));
-    }
-
-    /**
-     * Returns the request's payload contents as binary data, without processing
-     * any query string params (i.e. no form encoding for query params).
-     *
-     * @param request
-     *            The request
-     * @return The request's payload contents as binary data, not including any
-     *         form encoding of query string params.
-     */
-    protected byte[] getBinaryRequestPayloadWithoutQueryParams(SignableRequest<?> request) {
-        InputStream content = getBinaryRequestPayloadStreamWithoutQueryParams(request);
-
-        try {
-            ReadLimitInfo info = request.getReadLimitInfo();
-            content.mark(info == null ? -1 : info.getReadLimit());
-            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-            byte[] buffer = new byte[1024 * 5];
-            while (true) {
-                int bytesRead = content.read(buffer);
-                if (bytesRead == -1) break;
-
-                byteArrayOutputStream.write(buffer, 0, bytesRead);
-            }
-
-            byteArrayOutputStream.close();
-            content.reset();
-
-            return byteArrayOutputStream.toByteArray();
-        } catch (Exception e) {
-            throw new SdkClientException("Unable to read request payload to sign request: " + e.getMessage(), e);
-        }
-    }
-
-    protected InputStream getBinaryRequestPayloadStream(SignableRequest<?> request) {
-        if (SdkHttpUtils.usePayloadForQueryParameters(request)) {
-            String encodedParameters = SdkHttpUtils.encodeParameters(request);
-            if (encodedParameters == null)
-                return new ByteArrayInputStream(new byte[0]);
-
-            return new ByteArrayInputStream(
-                    encodedParameters.getBytes(UTF8));
-        }
-
-        return getBinaryRequestPayloadStreamWithoutQueryParams(request);
-    }
-
-    protected InputStream getBinaryRequestPayloadStreamWithoutQueryParams(SignableRequest<?> request) {
-        try {
-            InputStream is = request.getContentUnwrapped();
-            if (is == null)
-                return new ByteArrayInputStream(new byte[0]);
-            if (!is.markSupported())
-                throw new SdkClientException("Unable to read request payload to sign request.");
-            return is;
-        } catch (AmazonClientException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new SdkClientException("Unable to read request payload to sign request: " + e.getMessage(), e);
-        }
-    }
-
-    protected String getCanonicalizedResourcePath(String resourcePath) {
-        return getCanonicalizedResourcePath(resourcePath, true);
-    }
-
-    protected String getCanonicalizedResourcePath(String resourcePath, boolean urlEncode) {
-        if (resourcePath == null || resourcePath.isEmpty()) {
-            return "/";
-        } else {
-            String value = urlEncode ? SdkHttpUtils.urlEncode(resourcePath, true) : resourcePath;
-            if (value.startsWith("/")) {
-                return value;
-            } else {
-                return "/".concat(value);
-            }
-        }
-    }
-
-    protected String getCanonicalizedEndpoint(URI endpoint) {
-        String endpointForStringToSign = StringUtils.lowerCase(endpoint.getHost());
-        /*
-         * Apache HttpClient will omit the port in the Host header for default
-         * port values (i.e. 80 for HTTP and 443 for HTTPS) even if we
-         * explicitly specify it, so we need to be careful that we use the same
-         * value here when we calculate the string to sign and in the Host
-         * header we send in the HTTP request.
-         */
-        if (SdkHttpUtils.isUsingNonDefaultPort(endpoint)) {
-            endpointForStringToSign += ":" + endpoint.getPort();
-        }
-
-        return endpointForStringToSign;
-    }
-
-    /**
-     * Loads the individual access key ID and secret key from the specified
-     * credentials, ensuring that access to the credentials is synchronized on
-     * the credentials object itself, and trimming any extra whitespace from the
-     * credentials.
-     * <p>
-     * Returns either a {@link BasicSessionCredentials} or a
-     * {@link BasicAWSCredentials} object, depending on the input type.
-     *
-     * @param credentials
-     * @return A new credentials object with the sanitized credentials.
-     */
-    protected AWSCredentials sanitizeCredentials(AWSCredentials credentials) {
-        String accessKeyId = null;
-        String secretKey   = null;
-        String token = null;
-        synchronized (credentials) {
-            accessKeyId = credentials.getAWSAccessKeyId();
-            secretKey   = credentials.getAWSSecretKey();
-            if ( credentials instanceof AWSSessionCredentials ) {
-                token = ((AWSSessionCredentials) credentials).getSessionToken();
-            }
-        }
-        if (secretKey != null) secretKey = secretKey.trim();
-        if (accessKeyId != null) accessKeyId = accessKeyId.trim();
-        if (token != null) token = token.trim();
-
-        if (credentials instanceof AWSSessionCredentials) {
-            return new BasicSessionCredentials(accessKeyId, secretKey, token);
-        }
-
-        return new BasicAWSCredentials(accessKeyId, secretKey);
-    }
-
-    /**
-     * Safely converts a UTF-8 encoded byte array into a String.
-     *
-     * @param bytes UTF-8 encoded binary character data.
-     *
-     * @return The converted String object.
-     */
-    protected String newString(byte[] bytes) {
-        return new String(bytes, UTF8);
-    }
-
-    /**
-     * Returns the current time minus the given offset in seconds.
-     * The intent is to adjust the current time in the running JVM to the
-     * corresponding wall clock time at AWS for request signing purposes.
-     *
-     * @param offsetInSeconds
-     *            offset in seconds
-     */
-    protected Date getSignatureDate(int offsetInSeconds) {
-        return new Date(System.currentTimeMillis() - offsetInSeconds*1000);
-    }
-
-    /**
-     * Returns the time offset in seconds.
-     */
-    @Deprecated
-    protected int getTimeOffset(SignableRequest<?> request) {
-        final int globleOffset = SDKGlobalTime.getGlobalTimeOffset();
-        return globleOffset == 0 ? request.getTimeOffset() : globleOffset;
-    }
-
-    /**
-     * Adds session credentials to the request given.
-     *
-     * @param request
-     *            The request to add session credentials information to
-     * @param credentials
-     *            The session credentials to add to the request
-     */
-    protected abstract void addSessionCredentials(SignableRequest<?> request,
-            AWSSessionCredentials credentials);
-
-
-    /**
-     * Returns the re-usable thread local version of MessageDigest.
-     * @return
-     */
-    private static MessageDigest getMessageDigestInstance() {
-        MessageDigest messageDigest = SHA256_MESSAGE_DIGEST.get();
-        messageDigest.reset();
-        return messageDigest;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/AWS3Signer.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWS3Signer.java
--- ./src/main/java/com/amazonaws/auth/AWS3Signer.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWS3Signer.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,217 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import static com.amazonaws.util.StringUtils.UTF8;
-
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.UUID;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.SignableRequest;
-import com.amazonaws.log.InternalLogApi;
-import com.amazonaws.log.InternalLogFactory;
-import com.amazonaws.util.DateUtils;
-import com.amazonaws.util.SdkHttpUtils;
-import com.amazonaws.util.StringUtils;
-
-/**
- * Signer implementation that signs requests with the AWS3 signing protocol.
- */
-public class AWS3Signer extends AbstractAWSSigner {
-    private static final String AUTHORIZATION_HEADER = "X-Amzn-Authorization";
-    private static final String NONCE_HEADER = "x-amz-nonce";
-    private static final String HTTP_SCHEME = "AWS3";
-    private static final String HTTPS_SCHEME = "AWS3-HTTPS";
-
-    /** For internal testing only - allows the request's date to be overridden for testing. */
-    private String overriddenDate;
-
-    @Deprecated
-    protected static final DateUtils dateUtils = new DateUtils();
-    private static final InternalLogApi log = InternalLogFactory.getLog(AWS3Signer.class);
-
-
-    /**
-     * Signs the specified request with the AWS3 signing protocol by using the
-     * AWS account credentials specified when this object was constructed and
-     * adding the required AWS3 headers to the request.
-     *
-     * @param request
-     *            The request to sign.
-     */
-    @Override
-    public void sign(SignableRequest<?> request, AWSCredentials credentials) throws SdkClientException {
-        // annonymous credentials, don't sign
-        if ( credentials instanceof AnonymousAWSCredentials ) {
-            return;
-        }
-
-        AWSCredentials sanitizedCredentials = sanitizeCredentials(credentials);
-
-        SigningAlgorithm algorithm = SigningAlgorithm.HmacSHA256;
-        String nonce = UUID.randomUUID().toString();
-
-        int timeOffset = request.getTimeOffset();
-        Date dateValue = getSignatureDate(timeOffset);
-        String date = DateUtils.formatRFC822Date(dateValue);
-        boolean isHttps = false;
-
-        if (overriddenDate != null) date = overriddenDate;
-        request.addHeader("Date", date);
-        request.addHeader("X-Amz-Date", date);
-
-        // AWS3 HTTP requires that we sign the Host header
-        // so we have to have it in the request by the time we sign.
-        String hostHeader = request.getEndpoint().getHost();
-        if (SdkHttpUtils.isUsingNonDefaultPort(request.getEndpoint())) {
-            hostHeader += ":" + request.getEndpoint().getPort();
-        }
-        request.addHeader("Host", hostHeader);
-
-        if ( sanitizedCredentials instanceof AWSSessionCredentials ) {
-            addSessionCredentials(request, (AWSSessionCredentials) sanitizedCredentials);
-        }
-        byte[] bytesToSign;
-        String stringToSign;
-        if (isHttps) {
-            request.addHeader(NONCE_HEADER, nonce);
-            stringToSign = date + nonce;
-            bytesToSign = stringToSign.getBytes(UTF8);
-        } else {
-            String path = SdkHttpUtils.appendUri(request.getEndpoint().getPath(), request.getResourcePath());
-
-            /*
-             * AWS3 requires all query params to be listed on the third line of
-             * the string to sign, even if those query params will be sent in
-             * the request body and not as a query string. POST formatted query
-             * params should *NOT* be included in the request payload.
-             */
-            stringToSign = request.getHttpMethod().toString() + "\n"
-                    + getCanonicalizedResourcePath(path) + "\n"
-                    + getCanonicalizedQueryString(request.getParameters()) + "\n"
-                    + getCanonicalizedHeadersForStringToSign(request) + "\n"
-                    + getRequestPayloadWithoutQueryParams(request);
-            bytesToSign = hash(stringToSign);
-        }
-        if (log.isDebugEnabled())
-            log.debug("Calculated StringToSign: " + stringToSign);
-
-        String signature = signAndBase64Encode(bytesToSign,
-                sanitizedCredentials.getAWSSecretKey(), algorithm);
-
-        StringBuilder builder = new StringBuilder();
-        builder.append(isHttps ? HTTPS_SCHEME : HTTP_SCHEME).append(" ");
-        builder.append("AWSAccessKeyId=" + sanitizedCredentials.getAWSAccessKeyId() + ",");
-        builder.append("Algorithm=" + algorithm.toString() + ",");
-
-        if (!isHttps) {
-            builder.append(getSignedHeadersComponent(request) + ",");
-        }
-
-        builder.append("Signature=" + signature);
-        request.addHeader(AUTHORIZATION_HEADER, builder.toString());
-    }
-
-    private String getSignedHeadersComponent(SignableRequest<?> request) {
-        StringBuilder builder = new StringBuilder();
-        builder.append("SignedHeaders=");
-        boolean first = true;
-        for (String header : getHeadersForStringToSign(request)) {
-            if (!first) builder.append(";");
-            builder.append(header);
-            first = false;
-        }
-        return builder.toString();
-    }
-
-    protected List<String> getHeadersForStringToSign(SignableRequest<?> request) {
-        List<String> headersToSign = new ArrayList<String>();
-        for (Map.Entry<String, String> entry : request.getHeaders().entrySet()) {
-            String key = entry.getKey();
-            String lowerCaseKey = StringUtils.lowerCase(key);
-            if (lowerCaseKey.startsWith("x-amz")
-                    || lowerCaseKey.equals("host")) {
-                headersToSign.add(key);
-            }
-        }
-
-        Collections.sort(headersToSign);
-        return headersToSign;
-    }
-
-    /**
-     * For internal testing only - allows the date to be overridden for internal
-     * tests.
-     *
-     * @param date
-     *            The RFC822 date string to use when signing requests.
-     */
-    void overrideDate(String date) {
-        this.overriddenDate = date;
-    }
-
-    protected String getCanonicalizedHeadersForStringToSign(SignableRequest<?> request) {
-        List<String> headersToSign = getHeadersForStringToSign(request);
-
-        for (int i = 0; i < headersToSign.size(); i++) {
-            headersToSign.set(i, StringUtils.lowerCase(headersToSign.get(i)));
-        }
-
-        SortedMap<String, String> sortedHeaderMap = new TreeMap<String, String>();
-        for (Map.Entry<String, String> entry : request.getHeaders().entrySet()) {
-            if (headersToSign.contains(StringUtils.lowerCase(entry.getKey()))) {
-                sortedHeaderMap.put(StringUtils.lowerCase(entry.getKey()), entry.getValue());
-            }
-        }
-
-        StringBuilder builder = new StringBuilder();
-        for (Map.Entry<String, String> entry : sortedHeaderMap.entrySet()) {
-            builder.append(StringUtils.lowerCase(entry.getKey())).append(":")
-            .append(entry.getValue()).append("\n");
-        }
-
-        return builder.toString();
-    }
-
-    protected boolean shouldUseHttpsScheme(SignableRequest<?> request) throws SdkClientException {
-        try {
-            String protocol = StringUtils.lowerCase(request.getEndpoint().toURL().getProtocol());
-            if (protocol.equals("http")) {
-                return false;
-            } else if (protocol.equals("https")) {
-                return true;
-            } else {
-                throw new SdkClientException("Unknown request endpoint protocol " +
-                        "encountered while signing request: " + protocol);
-            }
-        } catch (MalformedURLException e) {
-            throw new SdkClientException("Unable to parse request endpoint during signing", e);
-        }
-    }
-
-    @Override
-    protected void addSessionCredentials(SignableRequest<?> request, AWSSessionCredentials credentials) {
-        request.addHeader("x-amz-security-token", credentials.getSessionToken());
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/AWS4Signer.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWS4Signer.java
--- ./src/main/java/com/amazonaws/auth/AWS4Signer.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWS4Signer.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,633 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.ReadLimitInfo;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.SignableRequest;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.auth.internal.AWS4SignerRequestParams;
-import com.amazonaws.auth.internal.AWS4SignerUtils;
-import com.amazonaws.auth.internal.SignerKey;
-import com.amazonaws.internal.FIFOCache;
-import com.amazonaws.log.InternalLogApi;
-import com.amazonaws.log.InternalLogFactory;
-import com.amazonaws.util.BinaryUtils;
-import com.amazonaws.util.DateUtils;
-import com.amazonaws.util.SdkHttpUtils;
-import com.amazonaws.util.StringUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import static com.amazonaws.auth.internal.SignerConstants.AUTHORIZATION;
-import static com.amazonaws.auth.internal.SignerConstants.AWS4_SIGNING_ALGORITHM;
-import static com.amazonaws.auth.internal.SignerConstants.AWS4_TERMINATOR;
-import static com.amazonaws.auth.internal.SignerConstants.HOST;
-import static com.amazonaws.auth.internal.SignerConstants.LINE_SEPARATOR;
-import static com.amazonaws.auth.internal.SignerConstants.PRESIGN_URL_MAX_EXPIRATION_SECONDS;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_ALGORITHM;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_CONTENT_SHA256;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_CREDENTIAL;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_DATE;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_EXPIRES;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SECURITY_TOKEN;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SIGNATURE;
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SIGNED_HEADER;
-
-/**
- * Signer implementation that signs requests with the AWS4 signing protocol.
- */
-public class AWS4Signer extends AbstractAWSSigner implements
-        ServiceAwareSigner, RegionAwareSigner, Presigner, EndpointPrefixAwareSigner {
-
-    protected static final InternalLogApi log = InternalLogFactory.getLog(AWS4Signer.class);
-    private static final int SIGNER_CACHE_MAX_SIZE = 300;
-    private static final FIFOCache<SignerKey> signerCache = new FIFOCache<SignerKey>(SIGNER_CACHE_MAX_SIZE);
-    private static final List<String> listOfHeadersToIgnoreInLowerCase = Arrays.asList("connection", "x-amzn-trace-id");
-
-    private final SdkClock clock;
-
-    /**
-     * Service name override for use when the endpoint can't be used to
-     * determine the service name.
-     */
-    protected String serviceName;
-
-    /**
-     * Endpoint prefix to compute the region name for signing
-     * when the {@link #regionName} is null.
-     */
-    private String endpointPrefix;
-
-    /**
-     * Region name override for use when the endpoint can't be used to determine
-     * the region name.
-     */
-    protected String regionName;
-
-    /** Date override for testing only */
-    protected Date overriddenDate;
-
-    /**
-     * Whether double url-encode the resource path when constructing the
-     * canonical request. By default, we enable double url-encoding.
-     *
-     * TODO: Different sigv4 services seem to be inconsistent on this. So for
-     * services that want to suppress this, they should use new
-     * AWS4Signer(false).
-     */
-    protected boolean doubleUrlEncode;
-
-    /**
-     * Construct a new AWS4 signer instance. By default, enable double
-     * url-encoding.
-     */
-    public AWS4Signer() {
-        this(true);
-    }
-
-    /**
-     * Construct a new AWS4 signer instance.
-     *
-     * @param doubleUrlEncoding
-     *            Whether double url-encode the resource path when constructing
-     *            the canonical request.
-     */
-    public AWS4Signer(boolean doubleUrlEncoding) {
-        this(doubleUrlEncoding, SdkClock.Instance.get());
-    }
-
-    @SdkTestInternalApi
-    public AWS4Signer(SdkClock clock) {
-        this(true, clock);
-    }
-
-    private AWS4Signer(boolean doubleUrlEncode, SdkClock clock) {
-        this.doubleUrlEncode = doubleUrlEncode;
-        this.clock = clock;
-    }
-
-    /**
-     * Sets the service name that this signer should use when calculating
-     * request signatures. This can almost always be determined directly from
-     * the request's end point, so you shouldn't need this method, but it's
-     * provided for the edge case where the information is not in the endpoint.
-     *
-     * @param serviceName
-     *            The service name to use when calculating signatures in this
-     *            signer.
-     */
-    @Override
-    public void setServiceName(String serviceName) {
-        this.serviceName = serviceName;
-    }
-
-    /**
-     * Sets the region name that this signer should use when calculating request
-     * signatures. This can almost always be determined directly from the
-     * request's end point, so you shouldn't need this method, but it's provided
-     * for the edge case where the information is not in the endpoint.
-     *
-     * @param regionName
-     *            The region name to use when calculating signatures in this
-     *            signer.
-     */
-    @Override
-    public void setRegionName(String regionName) {
-        this.regionName = regionName;
-    }
-
-    /**
-     * Sets the endpoint prefix which is used to compute the region that is
-     * used for signing the request.
-     *
-     * This value is passed to {@link AWS4SignerRequestParams} class which
-     * has the logic to compute region.
-     *
-     * @param endpointPrefix The endpoint prefix of the service
-     */
-    @Override
-    public void setEndpointPrefix(String endpointPrefix) {
-        this.endpointPrefix = endpointPrefix;
-    }
-
-    /**
-     * Sets the date that overrides the signing date in the request. This method
-     * is internal and should be used only for testing purposes.
-     */
-    @SdkTestInternalApi
-    public void setOverrideDate(Date overriddenDate) {
-        if (overriddenDate != null) {
-            this.overriddenDate = new Date(overriddenDate.getTime());
-        } else {
-            this.overriddenDate = null;
-        }
-    }
-
-    /**
-     * Returns the region name that is used when calculating the signature.
-     */
-    public String getRegionName() {
-        return regionName;
-    }
-
-    /**
-     * Returns the service name that is used when calculating the signature.
-     */
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    /**
-     * Returns a copy of date that overrides the signing date in the request.
-     * Return null by default.
-     */
-    public Date getOverriddenDate() {
-        return overriddenDate == null ? null : new Date(
-                overriddenDate.getTime());
-    }
-
-    @Override
-    public void sign(SignableRequest<?> request, AWSCredentials credentials) {
-        // anonymous credentials, don't sign
-        if (isAnonymous(credentials)) {
-            return;
-        }
-
-        AWSCredentials sanitizedCredentials = sanitizeCredentials(credentials);
-        if (sanitizedCredentials instanceof AWSSessionCredentials) {
-            addSessionCredentials(request,
-                    (AWSSessionCredentials) sanitizedCredentials);
-        }
-
-        final AWS4SignerRequestParams signerParams = new AWS4SignerRequestParams(
-                request, overriddenDate, regionName, serviceName,
-                AWS4_SIGNING_ALGORITHM, endpointPrefix);
-
-        addHostHeader(request);
-        request.addHeader(X_AMZ_DATE,
-                signerParams.getFormattedSigningDateTime());
-
-        String contentSha256 = calculateContentHash(request);
-
-        if ("required".equals(request.getHeaders().get(X_AMZ_CONTENT_SHA256))) {
-            request.addHeader(X_AMZ_CONTENT_SHA256, contentSha256);
-        }
-
-        final String canonicalRequest = createCanonicalRequest(request,
-                contentSha256);
-
-        final String stringToSign = createStringToSign(canonicalRequest,
-                signerParams);
-
-        final byte[] signingKey = deriveSigningKey(sanitizedCredentials,
-                signerParams);
-
-        final byte[] signature = computeSignature(stringToSign, signingKey,
-                signerParams);
-
-        request.addHeader(
-                AUTHORIZATION,
-                buildAuthorizationHeader(request, signature,
-                        sanitizedCredentials, signerParams));
-
-        processRequestPayload(request, signature, signingKey,
-                signerParams);
-    }
-
-    @Override
-    public void presignRequest(SignableRequest<?> request, AWSCredentials credentials,
-            Date userSpecifiedExpirationDate) {
-
-        // anonymous credentials, don't sign
-        if (isAnonymous(credentials)) {
-            return;
-        }
-
-        long expirationInSeconds = generateExpirationDate(userSpecifiedExpirationDate);
-
-        addHostHeader(request);
-
-        AWSCredentials sanitizedCredentials = sanitizeCredentials(credentials);
-        if (sanitizedCredentials instanceof AWSSessionCredentials) {
-            // For SigV4 pre-signing URL, we need to add "X-Amz-Security-Token"
-            // as a query string parameter, before constructing the canonical
-            // request.
-            request.addParameter(X_AMZ_SECURITY_TOKEN,
-                    ((AWSSessionCredentials) sanitizedCredentials)
-                            .getSessionToken());
-        }
-
-        final AWS4SignerRequestParams signerRequestParams = new AWS4SignerRequestParams(
-                request, overriddenDate, regionName, serviceName,
-                AWS4_SIGNING_ALGORITHM, endpointPrefix);
-
-        // Add the important parameters for v4 signing
-        final String timeStamp = signerRequestParams.getFormattedSigningDateTime();
-
-        addPreSignInformationToRequest(request, sanitizedCredentials,
-                signerRequestParams, timeStamp, expirationInSeconds);
-
-        final String contentSha256 = calculateContentHashPresign(request);
-
-        final String canonicalRequest = createCanonicalRequest(request,
-                contentSha256);
-
-        final String stringToSign = createStringToSign(canonicalRequest,
-                signerRequestParams);
-
-        final byte[] signingKey = deriveSigningKey(sanitizedCredentials,
-                signerRequestParams);
-
-        final byte[] signature = computeSignature(stringToSign, signingKey,
-                signerRequestParams);
-
-        request.addParameter(X_AMZ_SIGNATURE, BinaryUtils.toHex(signature));
-    }
-
-    /**
-     * Step 1 of the AWS Signature version 4 calculation. Refer to
-     * http://docs.aws
-     * .amazon.com/general/latest/gr/sigv4-create-canonical-request.html to
-     * generate the canonical request.
-     */
-    protected String createCanonicalRequest(SignableRequest<?> request,
-            String contentSha256) {
-        /* This would url-encode the resource path for the first time. */
-        final String path = SdkHttpUtils.appendUri(
-                request.getEndpoint().getPath(), request.getResourcePath());
-
-        final StringBuilder canonicalRequestBuilder = new StringBuilder(request
-                .getHttpMethod().toString());
-
-        canonicalRequestBuilder.append(LINE_SEPARATOR)
-                // This would optionally double url-encode the resource path
-                .append(getCanonicalizedResourcePath(path, doubleUrlEncode))
-                .append(LINE_SEPARATOR)
-                .append(getCanonicalizedQueryString(request))
-                .append(LINE_SEPARATOR)
-                .append(getCanonicalizedHeaderString(request))
-                .append(LINE_SEPARATOR)
-                .append(getSignedHeadersString(request)).append(LINE_SEPARATOR)
-                .append(contentSha256);
-
-        final String canonicalRequest = canonicalRequestBuilder.toString();
-
-        if (log.isDebugEnabled())
-            log.debug("AWS4 Canonical Request: '\"" + canonicalRequest + "\"");
-
-        return canonicalRequest;
-    }
-
-    /**
-     * Step 2 of the AWS Signature version 4 calculation. Refer to
-     * http://docs.aws
-     * .amazon.com/general/latest/gr/sigv4-create-string-to-sign.html.
-     */
-    protected String createStringToSign(String canonicalRequest,
-            AWS4SignerRequestParams signerParams) {
-
-        final StringBuilder stringToSignBuilder = new StringBuilder(
-                signerParams.getSigningAlgorithm());
-        stringToSignBuilder.append(LINE_SEPARATOR)
-                .append(signerParams.getFormattedSigningDateTime())
-                .append(LINE_SEPARATOR)
-                .append(signerParams.getScope())
-                .append(LINE_SEPARATOR)
-                .append(BinaryUtils.toHex(hash(canonicalRequest)));
-
-        final String stringToSign = stringToSignBuilder.toString();
-
-        if (log.isDebugEnabled())
-            log.debug("AWS4 String to Sign: '\"" + stringToSign + "\"");
-
-        return stringToSign;
-    }
-
-    /**
-     * Step 3 of the AWS Signature version 4 calculation. It involves deriving
-     * the signing key and computing the signature. Refer to
-     * http://docs.aws.amazon
-     * .com/general/latest/gr/sigv4-calculate-signature.html
-     */
-    private final byte[] deriveSigningKey(AWSCredentials credentials,
-            AWS4SignerRequestParams signerRequestParams) {
-
-        final String cacheKey = computeSigningCacheKeyName(credentials,
-                signerRequestParams);
-        final long daysSinceEpochSigningDate = DateUtils
-                .numberOfDaysSinceEpoch(signerRequestParams
-                        .getSigningDateTimeMilli());
-
-        SignerKey signerKey = signerCache.get(cacheKey);
-
-        if (signerKey != null) {
-            if (daysSinceEpochSigningDate == signerKey
-                    .getNumberOfDaysSinceEpoch()) {
-                return signerKey.getSigningKey();
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("Generating a new signing key as the signing key not available in the cache for the date "
-                    + TimeUnit.DAYS.toMillis(daysSinceEpochSigningDate));
-        }
-        byte[] signingKey = newSigningKey(credentials,
-                signerRequestParams.getFormattedSigningDate(),
-                signerRequestParams.getRegionName(),
-                signerRequestParams.getServiceName());
-        signerCache.add(cacheKey, new SignerKey(
-                daysSinceEpochSigningDate, signingKey));
-        return signingKey;
-    }
-
-    /**
-     * Computes the name to be used to reference the signing key in the cache.
-     */
-    private final String computeSigningCacheKeyName(AWSCredentials credentials,
-            AWS4SignerRequestParams signerRequestParams) {
-        final StringBuilder hashKeyBuilder = new StringBuilder(
-                credentials.getAWSSecretKey());
-
-        return hashKeyBuilder.append("-")
-                .append(signerRequestParams.getRegionName())
-                .append("-")
-                .append(signerRequestParams.getServiceName()).toString();
-    }
-
-    /**
-     * Step 3 of the AWS Signature version 4 calculation. It involves deriving
-     * the signing key and computing the signature. Refer to
-     * http://docs.aws.amazon
-     * .com/general/latest/gr/sigv4-calculate-signature.html
-     */
-    protected final byte[] computeSignature(String stringToSign,
-            byte[] signingKey, AWS4SignerRequestParams signerRequestParams) {
-        return sign(stringToSign.getBytes(Charset.forName("UTF-8")), signingKey,
-                SigningAlgorithm.HmacSHA256);
-    }
-
-    /**
-     * Creates the authorization header to be included in the request.
-     */
-    private String buildAuthorizationHeader(SignableRequest<?> request,
-            byte[] signature, AWSCredentials credentials,
-            AWS4SignerRequestParams signerParams) {
-        final String signingCredentials = credentials.getAWSAccessKeyId() + "/"
-                + signerParams.getScope();
-
-        final String credential = "Credential="
-                + signingCredentials;
-        final String signerHeaders = "SignedHeaders="
-                + getSignedHeadersString(request);
-        final String signatureHeader = "Signature="
-                + BinaryUtils.toHex(signature);
-
-        final StringBuilder authHeaderBuilder = new StringBuilder();
-
-        authHeaderBuilder.append(AWS4_SIGNING_ALGORITHM)
-                         .append(" ")
-                         .append(credential)
-                         .append(", ")
-                         .append(signerHeaders)
-                         .append(", ")
-                         .append(signatureHeader);
-
-        return authHeaderBuilder.toString();
-    }
-
-    /**
-     * Includes all the signing headers as request parameters for pre-signing.
-     */
-    private void addPreSignInformationToRequest(SignableRequest<?> request,
-            AWSCredentials credentials, AWS4SignerRequestParams signerParams,
-            String timeStamp, long expirationInSeconds) {
-
-        String signingCredentials = credentials.getAWSAccessKeyId() + "/"
-                + signerParams.getScope();
-
-        request.addParameter(X_AMZ_ALGORITHM, AWS4_SIGNING_ALGORITHM);
-        request.addParameter(X_AMZ_DATE, timeStamp);
-        request.addParameter(X_AMZ_SIGNED_HEADER,
-                getSignedHeadersString(request));
-        request.addParameter(X_AMZ_EXPIRES,
-                Long.toString(expirationInSeconds));
-        request.addParameter(X_AMZ_CREDENTIAL, signingCredentials);
-    }
-
-    @Override
-    protected void addSessionCredentials(SignableRequest<?> request,
-            AWSSessionCredentials credentials) {
-        request.addHeader(X_AMZ_SECURITY_TOKEN, credentials.getSessionToken());
-    }
-
-    protected String getCanonicalizedHeaderString(SignableRequest<?> request) {
-        final List<String> sortedHeaders = new ArrayList<String>(request.getHeaders()
-                .keySet());
-        Collections.sort(sortedHeaders, String.CASE_INSENSITIVE_ORDER);
-
-        final Map<String, String> requestHeaders = request.getHeaders();
-        StringBuilder buffer = new StringBuilder();
-        for (String header : sortedHeaders) {
-            if (shouldExcludeHeaderFromSigning(header)) {
-                continue;
-            }
-            String key = StringUtils.lowerCase(header);
-            String value = requestHeaders.get(header);
-
-            StringUtils.appendCompactedString(buffer, key);
-            buffer.append(":");
-            if (value != null) {
-                StringUtils.appendCompactedString(buffer, value);
-            }
-
-            buffer.append("\n");
-        }
-
-        return buffer.toString();
-    }
-
-    protected String getSignedHeadersString(SignableRequest<?> request) {
-        final List<String> sortedHeaders = new ArrayList<String>(request
-                .getHeaders().keySet());
-        Collections.sort(sortedHeaders, String.CASE_INSENSITIVE_ORDER);
-
-        StringBuilder buffer = new StringBuilder();
-        for (String header : sortedHeaders) {
-            if (shouldExcludeHeaderFromSigning(header)) {
-                continue;
-            }
-            if (buffer.length() > 0)
-                buffer.append(";");
-            buffer.append(StringUtils.lowerCase(header));
-        }
-
-        return buffer.toString();
-    }
-
-    protected boolean shouldExcludeHeaderFromSigning(String header) {
-        return listOfHeadersToIgnoreInLowerCase.contains(header.toLowerCase());
-    }
-
-    protected void addHostHeader(SignableRequest<?> request) {
-        // AWS4 requires that we sign the Host header so we
-        // have to have it in the request by the time we sign.
-
-        final URI endpoint = request.getEndpoint();
-        final StringBuilder hostHeaderBuilder = new StringBuilder(
-                endpoint.getHost());
-        if (SdkHttpUtils.isUsingNonDefaultPort(endpoint)) {
-            hostHeaderBuilder.append(":").append(endpoint.getPort());
-        }
-
-        request.addHeader(HOST, hostHeaderBuilder.toString());
-    }
-
-    /**
-     * Calculate the hash of the request's payload. Subclass could override this
-     * method to provide different values for "x-amz-content-sha256" header or
-     * do any other necessary set-ups on the request headers. (e.g. aws-chunked
-     * uses a pre-defined header value, and needs to change some headers
-     * relating to content-encoding and content-length.)
-     */
-    protected String calculateContentHash(SignableRequest<?> request) {
-        InputStream payloadStream = getBinaryRequestPayloadStream(request);
-        ReadLimitInfo info = request.getReadLimitInfo();
-        payloadStream.mark(info == null ? -1 : info.getReadLimit());
-        String contentSha256 = BinaryUtils.toHex(hash(payloadStream));
-        try {
-            payloadStream.reset();
-        } catch (IOException e) {
-            throw new SdkClientException(
-                    "Unable to reset stream after calculating AWS4 signature",
-                    e);
-        }
-        return contentSha256;
-    }
-
-    /**
-     * Subclass could override this method to perform any additional procedure
-     * on the request payload, with access to the result from signing the
-     * header. (e.g. Signing the payload by chunk-encoding). The default
-     * implementation doesn't need to do anything.
-     */
-    protected void processRequestPayload(SignableRequest<?> request, byte[] signature,
-            byte[] signingKey, AWS4SignerRequestParams signerRequestParams) {
-        return;
-    }
-
-    /**
-     * Calculate the hash of the request's payload. In case of pre-sign, the
-     * existing code would generate the hash of an empty byte array and returns
-     * it. This method can be overridden by sub classes to provide different
-     * values (e.g) For S3 pre-signing, the content hash calculation is
-     * different from the general implementation.
-     *
-     */
-    protected String calculateContentHashPresign(SignableRequest<?> request) {
-        return calculateContentHash(request);
-    }
-
-    /**
-     * Checks if the credentials is an instance of
-     * <code>AnonymousAWSCredentials<code>
-     */
-    private boolean isAnonymous(AWSCredentials credentials) {
-        return credentials instanceof AnonymousAWSCredentials;
-    }
-
-    /**
-     * Generates an expiration date for the presigned url. If user has specified
-     * an expiration date, check if it is in the given limit.
-     */
-    private long generateExpirationDate(Date expirationDate) {
-
-        long expirationInSeconds = expirationDate != null ? ((expirationDate
-                .getTime() - clock.currentTimeMillis()) / 1000L)
-                : PRESIGN_URL_MAX_EXPIRATION_SECONDS;
-
-        if (expirationInSeconds > PRESIGN_URL_MAX_EXPIRATION_SECONDS) {
-            throw new SdkClientException(
-                    "Requests that are pre-signed by SigV4 algorithm are valid for at most 7 days. "
-                            + "The expiration date set on the current request ["
-                            + AWS4SignerUtils.formatTimestamp(expirationDate
-                                    .getTime()) + "] has exceeded this limit.");
-        }
-        return expirationInSeconds;
-    }
-
-    /**
-     * Generates a new signing key from the given parameters and returns it.
-     */
-    protected byte[] newSigningKey(AWSCredentials credentials,
-            String dateStamp, String regionName, String serviceName) {
-        byte[] kSecret = ("AWS4" + credentials.getAWSSecretKey())
-                .getBytes(Charset.forName("UTF-8"));
-        byte[] kDate = sign(dateStamp, kSecret, SigningAlgorithm.HmacSHA256);
-        byte[] kRegion = sign(regionName, kDate, SigningAlgorithm.HmacSHA256);
-        byte[] kService = sign(serviceName, kRegion,
-                SigningAlgorithm.HmacSHA256);
-        return sign(AWS4_TERMINATOR, kService, SigningAlgorithm.HmacSHA256);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/AWS4UnsignedPayloadSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWS4UnsignedPayloadSigner.java
--- ./src/main/java/com/amazonaws/auth/AWS4UnsignedPayloadSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/AWS4UnsignedPayloadSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,55 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.SignableRequest;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.util.BinaryUtils;
-
-import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_CONTENT_SHA256;
-
-/**
- * Exactly the same as {@link AWS4Signer} except if the request is being sent
- * over HTTPS, then it returns the string <code>UNSIGNED-PAYLOAD</code> as the
- * content SHA-256 so services that support it can avoid needing to calculate
- * the value when authorizing the request.
- * <p>
- * Payloads are still signed for requests over HTTP to preserve the request
- * integrity over a non-secure transport.
- */
-public class AWS4UnsignedPayloadSigner extends AWS4Signer {
-    public AWS4UnsignedPayloadSigner() {
-        super();
-    }
-
-    @SdkTestInternalApi
-    public AWS4UnsignedPayloadSigner(SdkClock clock) {
-        super(clock);
-    }
-
-    @Override
-    public void sign(SignableRequest<?> request, AWSCredentials credentials) {
-        request.getHeaders().put(X_AMZ_CONTENT_SHA256, "required");
-        super.sign(request, credentials);
-    }
-
-    @Override
-    protected String calculateContentHash(SignableRequest<?> request) {
-        if ("https".equals(request.getEndpoint().getScheme())) {
-            return "UNSIGNED-PAYLOAD";
-        }
-        return super.calculateContentHash(request);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/CanHandleNullCredentials.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/CanHandleNullCredentials.java
--- ./src/main/java/com/amazonaws/auth/CanHandleNullCredentials.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/CanHandleNullCredentials.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.auth;
-
-import com.amazonaws.SignableRequest;
-
-/**
- * Used to explicitly indicate that a {@link com.amazonaws.auth.Signer} can gracefully handle
- * credentials being null when calling {@link com.amazonaws.auth.Signer#sign(SignableRequest, AWSCredentials)}
- */
-public interface CanHandleNullCredentials {}
diff -Nau8r ./src/main/java/com/amazonaws/auth/EndpointPrefixAwareSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EndpointPrefixAwareSigner.java
--- ./src/main/java/com/amazonaws/auth/EndpointPrefixAwareSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/EndpointPrefixAwareSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,36 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.auth;
-
-/**
- * A signer that knows the endpoint prefix of the AWS service.
- *
- * For example,
- * s3 is the endpoint prefix for Amazon S3 service.
- * iot is the endpoint prefix for AWS Iot service.
- *
- * The endpoint prefix will be used to compute the region to use
- * for signing if it is not already computed.
- */
-public interface EndpointPrefixAwareSigner extends Signer {
-
-    /**
-     * Configure the signer with the endpoint prefix
-     * of the service it is talking to.
-     *
-     * @param value The endpoint prefix of the service
-     */
-    void setEndpointPrefix(String value);
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/internal/AWS4SignerRequestParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/AWS4SignerRequestParams.java
--- ./src/main/java/com/amazonaws/auth/internal/AWS4SignerRequestParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/AWS4SignerRequestParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,199 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.internal;
-
-import com.amazonaws.auth.SdkClock;
-import java.util.Date;
-
-import com.amazonaws.SignableRequest;
-import com.amazonaws.util.AwsHostNameUtils;
-
-/**
- * Parameters that are used for computing a AWS 4 signature for a request.
- */
-public final class AWS4SignerRequestParams {
-
-    /**
-     * The request for which the signature needs to be computed.
-     */
-    private final SignableRequest<?> request;
-
-    /**
-     * The datetime in milliseconds for which the signature needs to be
-     * computed.
-     */
-    private final long signingDateTimeMilli;
-
-    /**
-     * The scope of the signature.
-     */
-    private final String scope;
-
-    /**
-     * The AWS region to be used for computing the signature.
-     */
-    private final String regionName;
-
-    /**
-     * The name of the AWS service.
-     */
-    private final String serviceName;
-
-    /**
-     * UTC formatted version of the signing time stamp.
-     */
-    private final String formattedSigningDateTime;
-
-    /**
-     * UTC Formatted Signing date with time stamp stripped
-     */
-    private final String formattedSigningDate;
-
-    /**
-     * The signing algorithm to be used for computing the signature.
-     */
-    private final String signingAlgorithm;
-
-    /**
-     * Generates an instance of AWS4signerRequestParams that holds the
-     * parameters used for computing a AWS 4 signature for a request
-     */
-    public AWS4SignerRequestParams(SignableRequest<?> request,
-            Date signingDateOverride, String regionNameOverride,
-            String serviceName, String signingAlgorithm) {
-        this(request, signingDateOverride, regionNameOverride,
-                serviceName, signingAlgorithm, null);
-    }
-
-    /**
-     * Generates an instance of AWS4signerRequestParams that holds the
-     * parameters used for computing a AWS 4 signature for a request
-     */
-    public AWS4SignerRequestParams(SignableRequest<?> request,
-                                   Date signingDateOverride, String regionNameOverride,
-                                   String serviceName, String signingAlgorithm,
-                                   String endpointPrefix) {
-        if (request == null) {
-            throw new IllegalArgumentException("Request cannot be null");
-        }
-        if (signingAlgorithm == null) {
-            throw new IllegalArgumentException(
-                    "Signing Algorithm cannot be null");
-        }
-        this.request = request;
-        this.signingDateTimeMilli = signingDateOverride != null ? signingDateOverride
-                .getTime() : getSigningDate(request);
-        this.formattedSigningDate = AWS4SignerUtils
-                .formatDateStamp(signingDateTimeMilli);
-        this.serviceName = serviceName;
-
-        this.regionName = regionNameOverride != null
-                ? regionNameOverride : resolveRegion(endpointPrefix, this.serviceName);
-
-        this.scope = generateScope(request, formattedSigningDate, this.serviceName,
-                regionName);
-        this.formattedSigningDateTime = AWS4SignerUtils
-                .formatTimestamp(signingDateTimeMilli);
-        this.signingAlgorithm = signingAlgorithm;
-    }
-
-    /*
-     * Ideally, we should be using endpoint prefix to parse the region from host.
-     *
-     * Previously we were using service signing name to parse region. It is possible that
-     * endpoint prefix is null if customers are still using older clients. So using
-     * service signing name as alternative will prevent any behavior breaking change.
-     */
-    private String resolveRegion(String endpointPrefix, String serviceSigningName) {
-
-        return AwsHostNameUtils.parseRegionName(request.getEndpoint().getHost(),
-                endpointPrefix != null ? endpointPrefix : serviceSigningName);
-    }
-
-    /**
-     * Returns the signing date from the request.
-     */
-    private final long getSigningDate(SignableRequest<?> request) {
-        return SdkClock.Instance.get().currentTimeMillis() - request.getTimeOffset() * 1000L;
-    }
-
-    /**
-     * Returns the scope to be used for the signing.
-     */
-    private String generateScope(SignableRequest<?> request, String dateStamp,
-            String serviceName, String regionName) {
-        final StringBuilder scopeBuilder = new StringBuilder();
-        return scopeBuilder.append(dateStamp).append("/").append(regionName)
-                .append("/").append(serviceName).append("/")
-                .append(SignerConstants.AWS4_TERMINATOR).toString();
-    }
-
-    /**
-     * Returns the request for which the signing needs to be done.
-     */
-    public SignableRequest<?> getRequest() {
-        return request;
-    }
-
-    /**
-     * Returns the scope of the signing.
-     */
-    public String getScope() {
-        return scope;
-    }
-
-    /**
-     * Returns the formatted date and time of the signing date in UTC zone.
-     */
-    public String getFormattedSigningDateTime() {
-        return formattedSigningDateTime;
-    }
-
-    /**
-     * Returns the signing date time in millis for which the signature needs to
-     * be computed.
-     */
-    public long getSigningDateTimeMilli() {
-        return signingDateTimeMilli;
-    }
-
-    /**
-     * Returns the AWS region name to be used while computing the signature.
-     */
-    public String getRegionName() {
-        return regionName;
-    }
-
-    /**
-     * Returns the AWS Service name to be used while computing the signature.
-     */
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    /**
-     * Returns the formatted date in UTC zone of the signing date.
-     */
-    public String getFormattedSigningDate() {
-        return formattedSigningDate;
-    }
-
-    /**
-     * Returns the signing algorithm used for computing the signature.
-     */
-    public String getSigningAlgorithm() {
-        return signingAlgorithm;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/internal/AWS4SignerUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/AWS4SignerUtils.java
--- ./src/main/java/com/amazonaws/auth/internal/AWS4SignerUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/AWS4SignerUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.internal;
-
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-
-/**
- * Utility methods that is used by the different AWS Signer implementations.
- * This class is strictly internal and is subjected to change.
- */
-public final class AWS4SignerUtils {
-
-    private static final DateTimeFormatter dateFormatter = DateTimeFormat
-            .forPattern("yyyyMMdd").withZoneUTC();
-
-    private static final DateTimeFormatter timeFormatter = DateTimeFormat
-            .forPattern("yyyyMMdd'T'HHmmss'Z'").withZoneUTC();
-
-    /**
-     * Returns a string representation of the given date time in yyyyMMdd
-     * format. The date returned is in the UTC zone.
-     *
-     * For example, given a time "1416863450581", this method returns "20141124"
-     */
-    public static String formatDateStamp(long timeMilli) {
-        return dateFormatter.print(timeMilli);
-    }
-
-    /**
-     * Returns a string representation of the given date time in
-     * yyyyMMdd'T'HHmmss'Z' format. The date returned is in the UTC zone.
-     *
-     * For example, given a time "1416863450581", this method returns
-     * "20141124T211050Z"
-     */
-    public static String formatTimestamp(long timeMilli) {
-        return timeFormatter.print(timeMilli);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/internal/SignerConstants.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/SignerConstants.java
--- ./src/main/java/com/amazonaws/auth/internal/SignerConstants.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/SignerConstants.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.internal;
-
-public final class SignerConstants {
-
-    public static final String LINE_SEPARATOR = "\n";
-
-    public static final String AWS4_TERMINATOR = "aws4_request";
-
-    public static final String AWS4_SIGNING_ALGORITHM = "AWS4-HMAC-SHA256";
-
-    /** Seconds in a week, which is the max expiration time Sig-v4 accepts */
-    public static final long PRESIGN_URL_MAX_EXPIRATION_SECONDS = 60 * 60 * 24 * 7;
-
-    public static final String X_AMZ_SECURITY_TOKEN = "X-Amz-Security-Token";
-
-    public static final String X_AMZ_CREDENTIAL = "X-Amz-Credential";
-
-    public static final String X_AMZ_DATE = "X-Amz-Date";
-
-    public static final String X_AMZ_EXPIRES = "X-Amz-Expires";
-
-    public static final String X_AMZ_SIGNED_HEADER = "X-Amz-SignedHeaders";
-
-    public static final String X_AMZ_CONTENT_SHA256 = "x-amz-content-sha256";
-
-    public static final String X_AMZ_SIGNATURE = "X-Amz-Signature";
-
-    public static final String X_AMZ_ALGORITHM = "X-Amz-Algorithm";
-
-    public static final String AUTHORIZATION = "Authorization";
-
-    public static final String HOST = "Host";
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/internal/SignerKey.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/SignerKey.java
--- ./src/main/java/com/amazonaws/auth/internal/SignerKey.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/internal/SignerKey.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,57 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.internal;
-
-import com.amazonaws.annotation.Immutable;
-
-/**
- * Holds the signing key and the number of days since epoch for the date for
- * which the signing key was generated.
- */
-@Immutable
-public final class SignerKey {
-
-    private final long numberOfDaysSinceEpoch;
-
-    private final byte[] signingKey;
-
-    public SignerKey(long numberOfDaysSinceEpoch, byte[] signingKey) {
-        if (numberOfDaysSinceEpoch <= 0L) {
-            throw new IllegalArgumentException(
-                    "Not able to cache signing key. Signing date to be cached is invalid");
-        }
-        if (signingKey == null) {
-            throw new IllegalArgumentException(
-                    "Not able to cache signing key. Signing Key to be cached are null");
-        }
-        this.numberOfDaysSinceEpoch = numberOfDaysSinceEpoch;
-        this.signingKey = signingKey.clone();
-    }
-
-    /**
-     * Returns the number of days since epoch for the date used for generating
-     * signing key.
-     */
-    public long getNumberOfDaysSinceEpoch() {
-        return numberOfDaysSinceEpoch;
-    }
-
-    /**
-     * Returns a copy of the signing key.
-     */
-    public byte[] getSigningKey() {
-        return signingKey.clone();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/NoOpSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/NoOpSigner.java
--- ./src/main/java/com/amazonaws/auth/NoOpSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/NoOpSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.SignableRequest;
-
-/**
- * A No-Op Signer Implementation.
- */
-public class NoOpSigner implements Signer {
-
-    @Override
-    public void sign(SignableRequest<?> request, AWSCredentials credentials) { }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/Action.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Action.java
--- ./src/main/java/com/amazonaws/auth/policy/Action.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Action.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy;
-
-/**
- * An access control policy action identifies a specific action in a service
- * that can be performed on a resource. For example, sending a message to a
- * queue.
- * <p>
- * Actions allow you to limit what your access control policy statement affects.
- * For example, you could create a policy statement that enables a certain group
- * of users to send messages to your queue, but not allow them to perform any
- * other actions on your queue.
- * <p>
- * The action is B in the statement
- * "A has permission to do B to C where D applies."
- * <p>
- * Free form access control policy actions may include a wildcard (*) to match
- * multiple actions.
- * <p>
- * This class is not intended to be directly implemented, instead developers
- * should see the classes available in com.amazonaws.auth.policy.actions for
- * more information on the available actions for each service.
- */
-public interface Action {
-
-    /**
-     * Returns the name of this action. For example, 'sqs:SendMessage' is the
-     * name corresponding to the SQS action that enables users to send a message
-     * to an SQS queue.
-     *
-     * @return The name of this action.
-     */
-    public String getActionName();
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/actions/package-info.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/actions/package-info.java
--- ./src/main/java/com/amazonaws/auth/policy/actions/package-info.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/actions/package-info.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,21 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-/**
- * Collection of actions for AWS access control policies.  Actions describe how
- * AWS resources are being accessed or modified when an AWS access control policy
- * is evaluated for an incoming request.
- */
-package com.amazonaws.auth.policy.actions;
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/Condition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Condition.java
--- ./src/main/java/com/amazonaws/auth/policy/Condition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Condition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,185 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy;
-
-import java.util.Arrays;
-import java.util.List;
-
-import com.amazonaws.auth.policy.conditions.ConditionFactory;
-import com.amazonaws.auth.policy.conditions.NumericCondition;
-import com.amazonaws.auth.policy.conditions.NumericCondition.NumericComparisonType;
-
-/**
- * AWS access control policy conditions are contained in {@link Statement}
- * objects, and affect when a statement is applied. For example, a statement
- * that allows access to an Amazon SQS queue could use a condition to only apply
- * the effect of that statement for requests that are made before a certain
- * date, or that originate from a range of IP addresses.
- * <p>
- * Multiple conditions can be included in a single statement, and all conditions
- * must evaluate to true in order for the statement to take effect.
- * <p>
- * The set of conditions is D in the statement
- * "A has permission to do B to C where D applies."
- * <p>
- * A condition is composed of three parts:
- * <ul>
- * <li><b>Condition Key</b> - The condition key declares which value of a
- * request to pull in and compare against when a policy is evaluated by AWS. For
- * example, using {@link ConditionFactory#SOURCE_IP_CONDITION_KEY} will cause
- * AWS to pull in the current request's source IP as the first value to compare
- * against every time your policy is evaluated.
- * <li><b>Comparison Type</b> - Most condition types allow several ways to
- * compare the value obtained from the condition key and the comparison value.
- * For example, the {@link NumericComparisonType} enumerates the ways a
- * {@link NumericCondition} can be evaluated (less than, greater than, equals,
- * etc).
- * <li><b>Comparison Value</b> - This is a static value used as the second value
- * in the comparison when your policy is evaluated. Depending on the comparison
- * type, this value can optionally use wildcards. See the documentation for
- * individual comparison types for more information.
- * </ul>
- * <p>
- * There are many expressive conditions available in the
- * <code>com.amazonaws.auth.policy.conditions</code> package to use in access
- * control policy statements.
- * <p>
- * This class is not intended to be directly subclassed by users, instead users
- * should use the many available conditions and condition factories in the
- * com.amazonaws.auth.policy.conditions package.
- */
-public class Condition {
-    protected String type;
-    protected String conditionKey;
-    protected List<String> values;
-
-    /**
-     * Returns the type of this condition.
-     *
-     * @return The type of this condition.
-     */
-    public String getType() {
-        return type;
-    }
-
-    /**
-     * Sets the type of this condition.
-     *
-     * @param type
-     *            The type of this condition.
-     */
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    /**
-     * Returns the name of the condition key involved in this condition.
-     * Condition keys are predefined values supported by AWS that provide input
-     * to a condition's evaluation, such as the current time, or the IP address
-     * of the incoming request.
-     * <p>
-     * Your policy is evaluated for each incoming request, and condition keys
-     * specify what information to pull out of those incoming requests and plug
-     * into the conditions in your policy.
-     *
-     * @return The name of the condition key involved in this condition.
-     */
-    public String getConditionKey() {
-        return conditionKey;
-    }
-
-    /**
-     * Sets the name of the condition key involved in this condition.
-     * Condition keys are predefined values supported by AWS that provide
-     * input to a condition's evaluation, such as the current time, or the IP
-     * address of the incoming request.
-     * <p>
-     * Your policy is evaluated for each incoming request, and condition keys
-     * specify what information to pull out of those incoming requests and plug
-     * into the conditions in your policy.
-     *
-     * @param conditionKey
-     *            The name of the condition key involved in this condition.
-     */
-    public void setConditionKey(String conditionKey) {
-        this.conditionKey = conditionKey;
-    }
-
-    /**
-     * Returns the values specified for this access control policy condition.
-     * For example, in a condition that compares the incoming IP address of a
-     * request to a specified range of IP addresses, the range of IP addresses
-     * is the single value in the condition.
-     * <p>
-     * Most conditions accept only one value, but multiple values are possible.
-     *
-     * @return The values specified for this access control policy condition.
-     */
-    public List<String> getValues() {
-        return values;
-    }
-
-    /**
-     * Sets the values specified for this access control policy condition. For
-     * example, in a condition that compares the incoming IP address of a
-     * request to a specified range of IP addresses, the range of IP addresses
-     * is the single value in the condition.
-     * <p>
-     * Most conditions accept only one value, but multiple values are possible.
-     *
-     * @param values
-     *            The values specified for this access control policy condition.
-     */
-    public void setValues(List<String> values) {
-        this.values = values;
-    }
-
-    /**
-     * Fluent version of {@link Condition#setType(String)}
-     * @return this
-     */
-    public Condition withType(String type) {
-        setType(type);
-        return this;
-    }
-
-    /**
-     * Fluent version of {@link Condition#setConditionKey(String)}
-     * @return this
-     */
-    public Condition withConditionKey(String key) {
-        setConditionKey(key);
-        return this;
-    }
-
-    /**
-     * Fluent version of {@link Condition#setValues(List)}
-     * @return this
-     */
-    public Condition withValues(String... values) {
-        setValues(Arrays.asList(values));
-        return this;
-    }
-
-
-    /**
-     * Fluent version of {@link Condition#setValues(List)}
-     * @return this
-     */
-    public Condition withValues(List<String> values) {
-        setValues(values);
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/ArnCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/ArnCondition.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/ArnCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/ArnCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,94 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import java.util.Arrays;
-
-import com.amazonaws.auth.policy.Condition;
-
-/**
- * AWS access control policy condition that allows an access control statement
- * to be conditionally applied based on the comparison of an Amazon Resource
- * Name (ARN).
- * <p>
- * An Amazon Resource Name (ARN) takes the following format:
- * <b>arn:aws:&lt;vendor>:&lt;region>:&lt;namespace>:&lt;relative-id></b>
- * <p>
- * <ul>
- * <li>vendor identifies the AWS product (e.g., sns)</li>
- * <li>region is the AWS Region the resource resides in (e.g., us-east-1), if
- * any
- * <li>namespace is the AWS account ID with no hyphens (e.g., 123456789012)
- * <li>relative-id is the service specific portion that identifies the specific
- * resource
- * </ul>
- * <p>
- * For example, an Amazon SQS queue might be addressed with the following ARN:
- * <b>arn:aws:sqs:us-east-1:987654321000:MyQueue</b>
- * <p>
- * <p>
- * Currently the only valid condition key to use in an ARN condition is
- * {@link ConditionFactory#SOURCE_ARN_CONDITION_KEY}, which indicates the
- * source resource that is modifying another resource, for example, an SNS topic
- * is the source ARN when publishing messages from the topic to an SQS queue.
- */
-public class ArnCondition extends Condition {
-
-    /**
-     * Enumeration of the supported ways an ARN comparison can be evaluated.
-     */
-    public static enum ArnComparisonType {
-        /** Exact matching */
-        ArnEquals,
-
-        /**
-         * Loose case-insensitive matching of the ARN. Each of the six
-         * colon-delimited components of the ARN is checked separately and each
-         * can include a multi-character match wildcard (*) or a
-         * single-character match wildcard (?).
-         */
-        ArnLike,
-
-        /** Negated form of {@link #ArnEquals} */
-        ArnNotEquals,
-
-        /** Negated form of {@link #ArnLike} */
-        ArnNotLike;
-    };
-
-    /**
-     * Constructs a new access control policy condition that compares ARNs
-     * (Amazon Resource Names).
-     *
-     * @param type
-     *            The type of comparison to perform.
-     * @param key
-     *            The access policy condition key specifying where to get the
-     *            first ARN for the comparison (ex:
-     *            {@link ConditionFactory#SOURCE_ARN_CONDITION_KEY}).
-     * @param value
-     *            The second ARN to compare against. When using
-     *            {@link ArnComparisonType#ArnLike} or
-     *            {@link ArnComparisonType#ArnNotLike} this may contain the
-     *            multi-character wildcard (*) or the single-character wildcard
-     *            (?).
-     */
-    public ArnCondition(ArnComparisonType type, String key, String value) {
-        super.type = type.toString();
-        super.conditionKey = key;
-        super.values = Arrays.asList(new String[] {value});
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/BooleanCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/BooleanCondition.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/BooleanCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/BooleanCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import java.util.Arrays;
-
-import com.amazonaws.auth.policy.Condition;
-
-/**
- * AWS access control policy condition that allows an access control statement to be
- * conditionally applied based on a comparison of boolean values.
- */
-public class BooleanCondition extends Condition {
-
-    /**
-     * Constructs a new access policy condition that performs a boolean
-     * comparison.
-     *
-     * @param key
-     *            The access policy condition key specifying where to get the
-     *            first boolean value for the comparison (ex:
-     *            aws:SecureTransport).
-     * @param value
-     *            The boolean to compare against.
-     */
-    public BooleanCondition(String key, boolean value) {
-        super.type = "Bool";
-        super.conditionKey = key;
-        super.values = Arrays.asList(new String[] {Boolean.toString(value)});
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/ConditionFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/ConditionFactory.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/ConditionFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/ConditionFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,174 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import com.amazonaws.auth.policy.Condition;
-import com.amazonaws.auth.policy.conditions.ArnCondition.ArnComparisonType;
-import com.amazonaws.auth.policy.conditions.StringCondition.StringComparisonType;
-
-/**
- * Factory for creating common AWS access control policy conditions. These
- * conditions are common for AWS services and can be expected to work across any
- * service that supports AWS access control policies.
- */
-public class ConditionFactory {
-
-    /**
-     * Condition key for the current time.
-     * <p>
-     * This condition key should only be used with {@link DateCondition}
-     * objects.
-     */
-    public static final String CURRENT_TIME_CONDITION_KEY = "aws:CurrentTime";
-
-    /**
-     * Condition key for whether or not an incoming request is using a secure
-     * transport to make the request (i.e. HTTPS instead of HTTP).
-     * <p>
-     * This condition key should only be used with {@link BooleanCondition}
-     * objects.
-     */
-    public static final String SECURE_TRANSPORT_CONDITION_KEY = "aws:SecureTransport";
-
-    /**
-     * Condition key for the source IP from which a request originates.
-     * <p>
-     * This condition key should only be used with {@link IpAddressCondition}
-     * objects.
-     */
-    public static final String SOURCE_IP_CONDITION_KEY = "aws:SourceIp";
-
-    /**
-     * Condition key for the user agent included in a request.
-     * <p>
-     * This condition key should only be used with {@link StringCondition}
-     * objects.
-     */
-    public static final String USER_AGENT_CONDITION_KEY = "aws:UserAgent";
-
-    /**
-     * Condition key for the current time, in epoch seconds.
-     * <p>
-     * This condition key should only be used with {@link NumericCondition}
-     * objects.
-     */
-    public static final String EPOCH_TIME_CONDITION_KEY = "aws:EpochTime";
-
-    /**
-     * Condition key for the referer specified by a request.
-     * <p>
-     * This condition key should only be used with {@link StringCondition}
-     * objects.
-     */
-    public static final String REFERER_CONDITION_KEY = "aws:Referer";
-
-    /**
-     * Condition key for the Amazon Resource Name (ARN) of the source specified
-     * in a request. The source ARN indicates which resource is affecting the
-     * resource listed in your policy. For example, an SNS topic is the source
-     * ARN when publishing messages from the topic to an SQS queue.
-     * <p>
-     * This condition key should only be used with {@link ArnCondition} objects.
-     */
-    public static final String SOURCE_ARN_CONDITION_KEY = "aws:SourceArn";
-
-    private ConditionFactory() {}
-
-    /**
-     * Constructs a new access policy condition that compares the Amazon
-     * Resource Name (ARN) of the source of an AWS resource that is modifying
-     * another AWS resource with the specified pattern.
-     * <p>
-     * For example, the source ARN could be an Amazon SNS topic ARN that is
-     * sending messages to an Amazon SQS queue. In that case, the SNS topic ARN
-     * would be compared the ARN pattern specified here.
-     * <p>
-     * The endpoint pattern may optionally contain the multi-character wildcard
-     * (*) or the single-character wildcard (?). Each of the six colon-delimited
-     * components of the ARN is checked separately and each can include a
-     * wildcard.
-     *
-     * <pre class="brush: java">
-     * Policy policy = new Policy(&quot;MyQueuePolicy&quot;);
-     * policy.withStatements(new Statement(&quot;AllowSNSMessages&quot;, Effect.Allow)
-     *         .withPrincipals(new Principal(&quot;*&quot;)).withActions(SQSActions.SendMessage)
-     *         .withResources(new Resource(myQueueArn))
-     *         .withConditions(ConditionFactory.newSourceArnCondition(myTopicArn)));
-     * </pre>
-     *
-     * @param arnPattern
-     *            The ARN pattern against which the source ARN will be compared.
-     *            Each of the six colon-delimited components of the ARN is
-     *            checked separately and each can include a wildcard.
-     *
-     * @return A new access control policy condition that compares the ARN of
-     *         the source specified in an incoming request with the ARN pattern
-     *         specified here.
-     */
-    public static Condition newSourceArnCondition(String arnPattern) {
-        return new ArnCondition(ArnComparisonType.ArnLike, SOURCE_ARN_CONDITION_KEY, arnPattern);
-    }
-
-    /**
-     * Constructs a new access control policy condition that tests if the
-     * incoming request was sent over a secure transport (HTTPS).
-     *
-     * @return A new access control policy condition that tests if the incoming
-     *         request was sent over a secure transport (HTTPS).
-     */
-    public static Condition newSecureTransportCondition() {
-        return new BooleanCondition(SECURE_TRANSPORT_CONDITION_KEY, true);
-    }
-
-    /**
-     * Constructs a new access control policy condition that tests the incoming
-     * request's user agent field against the specified value, using the
-     * specified comparison type. This condition can be used to allow or deny
-     * access to a resource based on what user agent is specified in the
-     * request.
-     *
-     * @param comparisonType
-     *            The type of string comparison to perform when testing an
-     *            incoming request's user agent field with the specified value.
-     * @param value
-     *            The value against which to compare the incoming request's user
-     *            agent.
-     *
-     * @return A new access control policy condition that tests an incoming
-     *         request's user agent field.
-     */
-    public static Condition newUserAgentCondition(StringComparisonType comparisonType, String value) {
-        return new StringCondition(comparisonType, USER_AGENT_CONDITION_KEY, value);
-    }
-
-    /**
-     * Constructs a new access control policy condition that tests the incoming
-     * request's referer field against the specified value, using the specified
-     * comparison type.
-     *
-     * @param comparisonType
-     *            The type of string comparison to perform when testing an
-     *            incoming request's referer field with the specified value.
-     * @param value
-     *            The value against which to compare the incoming request's
-     *            referer field.
-     *
-     * @return A new access control policy condition that tests an incoming
-     *         request's referer field.
-     */
-    public static Condition newRefererCondition(StringComparisonType comparisonType, String value) {
-        return new StringCondition(comparisonType, REFERER_CONDITION_KEY, value);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/DateCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/DateCondition.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/DateCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/DateCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import java.util.Arrays;
-import java.util.Date;
-
-import com.amazonaws.auth.policy.Condition;
-import com.amazonaws.util.DateUtils;
-
-/**
- * AWS access control policy condition that allows an access control statement
- * to be conditionally applied based on the comparison of the current time at
- * which a request is received, and a specific date.
- */
-public class DateCondition extends Condition {
-
-    /**
-     * Enumeration of the supported ways a date comparison can be evaluated.
-     */
-    public static enum DateComparisonType {
-        DateEquals,
-        DateGreaterThan,
-        DateGreaterThanEquals,
-        DateLessThan,
-        DateLessThanEquals,
-        DateNotEquals;
-    };
-
-    /**
-     * Constructs a new access policy condition that compares the current time
-     * (on the AWS servers) to the specified date.
-     *
-     * @param type
-     *            The type of comparison to perform. For example,
-     *            {@link DateComparisonType#DateLessThan} will cause this policy
-     *            condition to evaluate to true if the current date is less than
-     *            the date specified in the second argument.
-     * @param date
-     *            The date to compare against.
-     */
-    public DateCondition(DateComparisonType type, Date date) {
-        super.type = type.toString();
-        super.conditionKey = ConditionFactory.CURRENT_TIME_CONDITION_KEY;
-        super.values = Arrays.asList(new String[] {DateUtils.formatISO8601Date(date)});
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/IpAddressCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/IpAddressCondition.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/IpAddressCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/IpAddressCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,96 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import java.util.Arrays;
-
-import com.amazonaws.auth.policy.Condition;
-
-/**
- * AWS access control policy condition that allows an access control statement
- * to be conditionally applied based on the comparison of the the incoming
- * source IP address at the time of a request against a CIDR IP range.
- * <p>
- * For more information about CIDR IP ranges, see <a
- * href="http://en.wikipedia.org/wiki/CIDR_notation">
- * http://en.wikipedia.org/wiki/CIDR_notation</a>
- */
-public class IpAddressCondition extends Condition {
-
-    /**
-     * Enumeration of the supported ways an IP address comparison can be evaluated.
-     */
-    public static enum IpAddressComparisonType {
-        /**
-         * Matches an IP address against a CIDR IP range, evaluating to true if
-         * the IP address being tested is in the condition's specified CIDR IP
-         * range.
-         * <p>
-         * For more information about CIDR IP ranges, see <a
-         * href="http://en.wikipedia.org/wiki/CIDR_notation">
-         * http://en.wikipedia.org/wiki/CIDR_notation</a>
-         */
-        IpAddress,
-
-        /** Negated form of {@link #IpAddress} */
-        NotIpAddress,
-    }
-
-    /**
-     * Constructs a new access policy condition that compares the source IP
-     * address of the incoming request to an AWS service against the specified
-     * CIDR range. The condition evaluates to true (meaning the policy statement
-     * containing it will be applied) if the incoming source IP address is
-     * within that range.
-     * <p>
-     * To achieve the opposite effect (i.e. cause the condition to evaluate to
-     * true when the incoming source IP is <b>not</b> in the specified CIDR
-     * range) use the alternate constructor form and specify
-     * {@link IpAddressComparisonType#NotIpAddress}
-     * <p>
-     * For more information about CIDR IP ranges, see <a
-     * href="http://en.wikipedia.org/wiki/CIDR_notation">
-     * http://en.wikipedia.org/wiki/CIDR_notation</a>
-     *
-     * @param ipAddressRange
-     *            The CIDR IP range involved in the policy condition.
-     */
-    public IpAddressCondition(String ipAddressRange) {
-        this(IpAddressComparisonType.IpAddress, ipAddressRange);
-    }
-
-    /**
-     * Constructs a new access policy condition that compares the source IP
-     * address of the incoming request to an AWS service against the specified
-     * CIDR range. When the condition evaluates to true (i.e. when the incoming
-     * source IP address is within the CIDR range or not) depends on the
-     * specified {@link IpAddressComparisonType}.
-     * <p>
-     * For more information about CIDR IP ranges, see <a
-     * href="http://en.wikipedia.org/wiki/CIDR_notation">
-     * http://en.wikipedia.org/wiki/CIDR_notation</a>
-     *
-     * @param type
-     *            The type of comparison to to perform.
-     * @param ipAddressRange
-     *            The CIDR IP range involved in the policy condition.
-     */
-    public IpAddressCondition(IpAddressComparisonType type, String ipAddressRange) {
-        super.type = type.toString();
-        super.conditionKey = ConditionFactory.SOURCE_IP_CONDITION_KEY;
-        super.values = Arrays.asList(new String[] {ipAddressRange});
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/NumericCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/NumericCondition.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/NumericCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/NumericCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import java.util.Arrays;
-
-import com.amazonaws.auth.policy.Condition;
-
-/**
- * AWS access control policy condition that allows an access control statement to be
- * conditionally applied based on a numeric comparison.
- */
-public class NumericCondition extends Condition {
-
-    /** Enumeration of the supported ways a numeric comparison can be evaluated */
-    public static enum NumericComparisonType {
-        NumericEquals,
-        NumericGreaterThan,
-        NumericGreaterThanEquals,
-        NumericLessThan,
-        NumericLessThanEquals,
-        NumericNotEquals;
-    };
-
-    /**
-     * Constructs a new access policy condition that compares two numbers.
-     *
-     * @param type
-     *            The type of comparison to perform.
-     * @param key
-     *            The access policy condition key specifying where to get the
-     *            first number for the comparison.
-     * @param value
-     *            The second number to compare against.
-     */
-    public NumericCondition(NumericComparisonType type, String key, String value) {
-        super.type = type.toString();
-        super.conditionKey = key;
-        super.values = Arrays.asList(new String[] {value});
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/package-info.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/package-info.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/package-info.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/package-info.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-/**
- * Collection of AWS access control policy conditions.  The primary access policy
- * conditions are:
- * <ul>
- *    <li> {@link com.amazonaws.auth.policy.conditions.ArnCondition}
- *    <li> {@link com.amazonaws.auth.policy.conditions.BooleanCondition}
- *    <li> {@link com.amazonaws.auth.policy.conditions.DateCondition}
- *    <li> {@link com.amazonaws.auth.policy.conditions.IpAddressCondition}
- *    <li> {@link com.amazonaws.auth.policy.conditions.NumericCondition}
- *    <li> {@link com.amazonaws.auth.policy.conditions.StringCondition}
- * </ul>
- *
- * <p>
- * In addition to the primary condition types, service specific functionality
- * is also provided.
- */
-package com.amazonaws.auth.policy.conditions;
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/conditions/StringCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/StringCondition.java
--- ./src/main/java/com/amazonaws/auth/policy/conditions/StringCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/conditions/StringCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,78 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.conditions;
-
-import java.util.Arrays;
-
-import com.amazonaws.auth.policy.Condition;
-
-/**
- * String conditions let you constrain AWS access control policy statements
- * using string matching rules.
- */
-public class StringCondition extends Condition {
-
-    /**
-     * Enumeration of the supported ways a string comparison can be evaluated.
-     */
-    public static enum StringComparisonType {
-        /** Case-sensitive exact string matching */
-        StringEquals,
-
-        /** Case-insensitive string matching */
-        StringEqualsIgnoreCase,
-
-        /**
-         * Loose case-insensitive matching. The values can include a
-         * multi-character match wildcard (*) or a single-character match
-         * wildcard (?) anywhere in the string.
-         */
-        StringLike,
-
-        /** Negated form of {@link #StringEquals} */
-        StringNotEquals,
-
-        /** Negated form of {@link #StringEqualsIgnoreCase} */
-        StringNotEqualsIgnoreCase,
-
-        /** Negated form of {@link #StringLike} */
-        StringNotLike;
-    }
-
-    /**
-     * Constructs a new access control policy condition that compares two
-     * strings.
-     *
-     * @param type
-     *            The type of comparison to perform.
-     * @param key
-     *            The access policy condition key specifying where to get the
-     *            first string for the comparison (ex: aws:UserAgent). See
-     *            {@link ConditionFactory} for a list of the condition keys
-     *            available for all services.
-     * @param value
-     *            The second string to compare against. When using
-     *            {@link StringComparisonType#StringLike} or
-     *            {@link StringComparisonType#StringNotLike} this may contain
-     *            the multi-character wildcard (*) or the single-character
-     *            wildcard (?).
-     */
-    public StringCondition(StringComparisonType type, String key, String value) {
-        super.type = type.toString();
-        super.conditionKey = key;
-        super.values = Arrays.asList(new String[] {value});
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/internal/JsonDocumentFields.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/internal/JsonDocumentFields.java
--- ./src/main/java/com/amazonaws/auth/policy/internal/JsonDocumentFields.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/internal/JsonDocumentFields.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.internal;
-
-public class JsonDocumentFields {
-     public static final String VERSION = "Version";
-     public static final String POLICY_ID = "Id";
-     public static final String STATEMENT = "Statement";
-     public static final String STATEMENT_EFFECT = "Effect";
-     public static final String EFFECT_VALUE_ALLOW = "Allow";
-     public static final String STATEMENT_ID = "Sid";
-     public static final String PRINCIPAL = "Principal";
-     public static final String ACTION = "Action";
-     public static final String RESOURCE = "Resource";
-     public static final String CONDITION = "Condition";
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyReader.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyReader.java
--- ./src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyReader.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyReader.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,354 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.internal;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.auth.policy.Action;
-import com.amazonaws.auth.policy.Condition;
-import com.amazonaws.auth.policy.Policy;
-import com.amazonaws.auth.policy.PolicyReaderOptions;
-import com.amazonaws.auth.policy.Principal;
-import com.amazonaws.auth.policy.Principal.WebIdentityProviders;
-import com.amazonaws.auth.policy.Resource;
-import com.amazonaws.auth.policy.Statement;
-import com.amazonaws.auth.policy.Statement.Effect;
-import com.amazonaws.util.json.Jackson;
-import com.fasterxml.jackson.databind.JsonNode;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Generate an AWS policy object by parsing the given JSON string.
- */
-public class JsonPolicyReader {
-
-    private static final String PRINCIPAL_SCHEMA_USER = "AWS";
-
-    private static final String PRINCIPAL_SCHEMA_SERVICE = "Service";
-
-    private static final String PRINCIPAL_SCHEMA_FEDERATED = "Federated";
-
-    private final PolicyReaderOptions options;
-
-    public JsonPolicyReader() {
-        this(new PolicyReaderOptions());
-    }
-
-    public JsonPolicyReader(PolicyReaderOptions options) {
-        this.options = options;
-    }
-
-    /**
-     * Converts the specified JSON string to an AWS policy object.
-     *
-     * For more information see, @see
-     * http://docs.aws.amazon.com/AWSSdkDocsJava/latest
-     * /DeveloperGuide/java-dg-access-control.html
-     *
-     * @param jsonString
-     *            the specified JSON string representation of this AWS access
-     *            control policy.
-     *
-     * @return An AWS policy object.
-     *
-     * @throws IllegalArgumentException
-     *             If the specified JSON string is null or invalid and cannot be
-     *             converted to an AWS policy object.
-     */
-    public Policy createPolicyFromJsonString(String jsonString) {
-        if (jsonString == null) {
-            throw new IllegalArgumentException("JSON string cannot be null");
-        }
-
-        JsonNode policyNode;
-        JsonNode idNode;
-        JsonNode statementNodes;
-        Policy policy = new Policy();
-        List<Statement> statements = new LinkedList<Statement>();
-
-        try {
-            policyNode = Jackson.jsonNodeOf(jsonString);
-
-            idNode = policyNode.get(JsonDocumentFields.POLICY_ID);
-            if (isNotNull(idNode)) {
-                policy.setId(idNode.asText());
-            }
-
-            statementNodes = policyNode.get(JsonDocumentFields.STATEMENT);
-            if (isNotNull(statementNodes)) {
-                for (JsonNode node : statementNodes) {
-                    statements.add(statementOf(node));
-                }
-            }
-
-        } catch (Exception e) {
-            String message = "Unable to generate policy object fron JSON string "
-                    + e.getMessage();
-            throw new IllegalArgumentException(message, e);
-        }
-        policy.setStatements(statements);
-        return policy;
-    }
-
-    /**
-     * Creates a <code>Statement<code> instance from the statement node.
-     *
-     * A statement consists of an Effect, id (optional), principal, action, resource,
-     * and conditions.
-     * <p>
-     * principal is the AWS account that is making a request to access or modify one of your AWS resources.
-     * <p>
-     * action is the way in which your AWS resource is being accessed or modified, such as sending a message to an Amazon SQS queue, or storing an object in an Amazon S3 bucket.
-     * <p>
-     * resource is the AWS entity that the principal wants to access, such as an Amazon SQS queue, or an object stored in Amazon S3.
-     * <p>
-     * conditions are the optional constraints that specify when to allow or deny access for the principal to access your resource. Many expressive conditions are available, some specific to each service. For example, you can use date conditions to allow access to your resources only after or before a specific time.
-     *
-     * @param jStatement
-     *            JsonNode representing the statement.
-     * @return a reference to the statement instance created.
-     */
-    private Statement statementOf(JsonNode jStatement) {
-
-        JsonNode effectNode = jStatement.get(JsonDocumentFields.STATEMENT_EFFECT);
-
-        final Effect effect = isNotNull(effectNode)
-                                   ? Effect.valueOf(effectNode.asText())
-                                   : Effect.Deny ;
-
-        Statement statement = new Statement(effect);
-
-        JsonNode id = jStatement.get(JsonDocumentFields.STATEMENT_ID);
-        if (isNotNull(id)) {
-            statement.setId(id.asText());
-        }
-
-        JsonNode actionNodes = jStatement.get(JsonDocumentFields.ACTION);
-        if (isNotNull(actionNodes))
-            statement.setActions(actionsOf(actionNodes));
-
-        JsonNode resourceNodes = jStatement.get(JsonDocumentFields.RESOURCE);
-        if (isNotNull(resourceNodes))
-            statement.setResources(resourcesOf(resourceNodes));
-
-        JsonNode conditionNodes = jStatement.get(JsonDocumentFields.CONDITION);
-        if (isNotNull(conditionNodes))
-            statement.setConditions(conditionsOf(conditionNodes));
-
-        JsonNode principalNodes = jStatement.get(JsonDocumentFields.PRINCIPAL);
-        if (isNotNull(principalNodes))
-            statement.setPrincipals(principalOf(principalNodes));
-
-        return statement;
-    }
-
-    /**
-     * Generates a list of actions from the Action Json Node.
-     *
-     * @param actionNodes
-     *            the action Json node to be parsed.
-     * @return the list of actions.
-     */
-    private List<Action> actionsOf(JsonNode actionNodes) {
-        List<Action> actions = new LinkedList<Action>();
-
-        if (actionNodes.isArray()) {
-            for (JsonNode action : actionNodes) {
-                actions.add(new NamedAction(action.asText()));
-            }
-        } else {
-            actions.add(new NamedAction(actionNodes.asText()));
-        }
-        return actions;
-    }
-
-    /**
-     * Generates a list of resources from the Resource Json Node.
-     *
-     * @param resourceNodes
-     *            the resource Json node to be parsed.
-     * @return the list of resources.
-     */
-    private List<Resource> resourcesOf(JsonNode resourceNodes) {
-        List<Resource> resources = new LinkedList<Resource>();
-
-        if (resourceNodes.isArray()) {
-            for (JsonNode resource : resourceNodes) {
-                resources.add(new Resource(resource.asText()));
-            }
-        } else {
-            resources.add(new Resource(resourceNodes.asText()));
-        }
-
-        return resources;
-    }
-
-    /**
-     * Generates a list of principals from the Principal Json Node
-     *
-     * @param principalNodes
-     *            the principal Json to be parsed
-     * @return a list of principals
-     */
-    private List<Principal> principalOf(JsonNode principalNodes) {
-        List<Principal> principals = new LinkedList<Principal>();
-
-        if (principalNodes.asText().equals("*")) {
-            principals.add(Principal.All);
-            return principals;
-        }
-
-        Iterator<Map.Entry<String, JsonNode>> mapOfPrincipals = principalNodes
-                .fields();
-        String schema;
-        JsonNode principalNode;
-        Entry<String, JsonNode> principal;
-        Iterator<JsonNode> elements;
-        while (mapOfPrincipals.hasNext()) {
-            principal = mapOfPrincipals.next();
-            schema = principal.getKey();
-            principalNode = principal.getValue();
-
-            if (principalNode.isArray()) {
-                elements = principalNode.elements();
-                while (elements.hasNext()) {
-                    principals.add(createPrincipal(schema, elements.next()));
-                }
-            } else {
-                principals.add(createPrincipal(schema, principalNode));
-            }
-        }
-
-        return principals;
-    }
-
-    /**
-     * Creates a new principal instance for the given schema and the Json node.
-     *
-     * @param schema
-     *            the schema for the principal instance being created.
-     * @param principalNode
-     *            the node indicating the AWS account that is making the
-     *            request.
-     * @return a principal instance.
-     */
-    private Principal createPrincipal(String schema, JsonNode principalNode) {
-        if (schema.equalsIgnoreCase(PRINCIPAL_SCHEMA_USER)) {
-            return new Principal(PRINCIPAL_SCHEMA_USER, principalNode.asText(), options.isStripAwsPrincipalIdHyphensEnabled());
-        } else if (schema.equalsIgnoreCase(PRINCIPAL_SCHEMA_SERVICE)) {
-            return new Principal(schema, principalNode.asText());
-        } else if (schema.equalsIgnoreCase(PRINCIPAL_SCHEMA_FEDERATED)) {
-            if (WebIdentityProviders.fromString(principalNode.asText()) != null) {
-                return new Principal(WebIdentityProviders.fromString(principalNode.asText()));
-            } else {
-                return new Principal(PRINCIPAL_SCHEMA_FEDERATED, principalNode.asText());
-            }
-        }
-        throw new SdkClientException("Schema " + schema + " is not a valid value for the principal.");
-    }
-
-    /**
-     * Generates a list of condition from the Json node.
-     *
-     * @param conditionNodes
-     *            the condition Json node to be parsed.
-     * @return the list of conditions.
-     */
-    private List<Condition> conditionsOf(JsonNode conditionNodes) {
-
-        List<Condition> conditionList = new LinkedList<Condition>();
-        Iterator<Map.Entry<String, JsonNode>> mapOfConditions = conditionNodes
-                .fields();
-
-        Entry<String, JsonNode> condition;
-        while (mapOfConditions.hasNext()) {
-            condition = mapOfConditions.next();
-            convertConditionRecord(conditionList, condition.getKey(),
-                    condition.getValue());
-        }
-
-        return conditionList;
-    }
-
-    /**
-     * Generates a condition instance for each condition type under the
-     * Condition Json node.
-     *
-     * @param conditions
-     *            the complete list of conditions
-     * @param conditionType
-     *            the condition type for the condition being created.
-     * @param conditionNode
-     *            each condition node to be parsed.
-     */
-    private void convertConditionRecord(List<Condition> conditions,
-            String conditionType, JsonNode conditionNode) {
-
-        Iterator<Map.Entry<String, JsonNode>> mapOfFields = conditionNode
-                .fields();
-        List<String> values;
-        Entry<String, JsonNode> field;
-        JsonNode fieldValue;
-        Iterator<JsonNode> elements;
-
-        while (mapOfFields.hasNext()) {
-            values = new LinkedList<String>();
-            field = mapOfFields.next();
-            fieldValue = field.getValue();
-
-            if (fieldValue.isArray()) {
-                elements = fieldValue.elements();
-                while (elements.hasNext()) {
-                    values.add(elements.next().asText());
-                }
-            } else {
-                values.add(fieldValue.asText());
-            }
-            conditions.add(new Condition().withType(conditionType)
-                    .withConditionKey(field.getKey()).withValues(values));
-        }
-    }
-
-    /**
-     * An auxiliary class to help instantiate the action object.
-     */
-    private static class NamedAction implements Action {
-
-        private String actionName;
-
-        public NamedAction(String actionName) {
-            this.actionName = actionName;
-        }
-
-        public String getActionName() {
-            return actionName;
-        }
-
-    }
-
-    /**
-     * Checks if the given object is not null.
-     *
-     * @param object
-     *            the object compared to null.
-     * @return true if the object is not null else false
-     */
-    private boolean isNotNull(Object object) {
-        return null != object;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyWriter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyWriter.java
--- ./src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyWriter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/internal/JsonPolicyWriter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,414 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy.internal;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.auth.policy.Action;
-import com.amazonaws.auth.policy.Condition;
-import com.amazonaws.auth.policy.Policy;
-import com.amazonaws.auth.policy.Principal;
-import com.amazonaws.auth.policy.Resource;
-import com.amazonaws.auth.policy.Statement;
-import com.amazonaws.util.json.Jackson;
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Serializes an AWS policy object to a JSON string, suitable for sending to an
- * AWS service.
- */
-public class JsonPolicyWriter {
-
-    /** The JSON Generator to generator a JSON string.*/
-    private JsonGenerator generator = null;
-
-    /** The output writer to which the JSON String is written.*/
-    private Writer writer;
-
-    /** Logger used to log exceptions that occurs while writing the Json policy.*/
-    private static final Log log = LogFactory.getLog("com.amazonaws.auth.policy");
-
-    /**
-     * Constructs a new instance of JSONPolicyWriter.
-     */
-    public JsonPolicyWriter() {
-        writer = new StringWriter();
-        try {
-            generator = Jackson.jsonGeneratorOf(writer);
-        } catch (IOException ioe) {
-            throw new SdkClientException(
-                    "Unable to instantiate JsonGenerator.", ioe);
-        }
-
-    }
-
-    /**
-     * Converts the specified AWS policy object to a JSON string, suitable for
-     * passing to an AWS service.
-     *
-     * @param policy
-     *            The AWS policy object to convert to a JSON string.
-     *
-     * @return The JSON string representation of the specified policy object.
-     *
-     * @throws IllegalArgumentException
-     *             If the specified policy is null or invalid and cannot be
-     *             serialized to a JSON string.
-     */
-    public String writePolicyToString(Policy policy) {
-
-        if(!isNotNull(policy))
-            throw new IllegalArgumentException("Policy cannot be null");
-
-        try {
-            return jsonStringOf(policy);
-        } catch (Exception e) {
-            String message = "Unable to serialize policy to JSON string: "
-                    + e.getMessage();
-            throw new IllegalArgumentException(message, e);
-        } finally {
-            try { writer.close(); } catch (Exception e) { }
-        }
-    }
-
-    /**
-     * Converts the given <code>Policy</code> into a JSON String.
-     *
-     * @param policy
-     *            the policy to be converted.
-     * @return a JSON String of the specified policy object.
-     */
-    private String jsonStringOf(Policy policy) throws JsonGenerationException,
-            IOException {
-        generator.writeStartObject();
-
-        writeJsonKeyValue(JsonDocumentFields.VERSION, policy.getVersion());
-
-        if (isNotNull(policy.getId()))
-            writeJsonKeyValue(JsonDocumentFields.POLICY_ID, policy.getId());
-
-        writeJsonArrayStart(JsonDocumentFields.STATEMENT);
-
-        for (Statement statement : policy.getStatements()) {
-            generator.writeStartObject();
-
-            if (isNotNull(statement.getId())) {
-                writeJsonKeyValue(JsonDocumentFields.STATEMENT_ID, statement.getId());
-            }
-            writeJsonKeyValue(JsonDocumentFields.STATEMENT_EFFECT, statement
-                    .getEffect().toString());
-
-            List<Principal> principals = statement.getPrincipals();
-            if (isNotNull(principals) && !principals.isEmpty())
-                writePrincipals(principals);
-
-            List<Action> actions = statement.getActions();
-            if (isNotNull(actions) && !actions.isEmpty())
-                writeActions(actions);
-
-            List<Resource> resources = statement.getResources();
-            if (isNotNull(resources) && !resources.isEmpty())
-                writeResources(resources);
-
-            List<Condition> conditions = statement.getConditions();
-            if (isNotNull(conditions) && !conditions.isEmpty())
-                writeConditions(conditions);
-
-            generator.writeEndObject();
-        }
-
-        writeJsonArrayEnd();
-
-        generator.writeEndObject();
-
-        generator.flush();
-
-        return writer.toString();
-
-    }
-
-    /**
-     * Writes the list of conditions to the JSONGenerator.
-     *
-     * @param conditions
-     *            the conditions to be written.
-     */
-    private void writeConditions(List<Condition> conditions)
-            throws JsonGenerationException, IOException {
-        Map<String, ConditionsByKey> conditionsByType = groupConditionsByTypeAndKey(conditions);
-
-        writeJsonObjectStart(JsonDocumentFields.CONDITION);
-
-        ConditionsByKey conditionsByKey;
-        for (Map.Entry<String, ConditionsByKey> entry : conditionsByType
-                .entrySet()) {
-            conditionsByKey = conditionsByType.get(entry.getKey());
-
-            writeJsonObjectStart(entry.getKey());
-            for (String key : conditionsByKey.keySet()) {
-                writeJsonArray(key, conditionsByKey.getConditionsByKey(key));
-            }
-            writeJsonObjectEnd();
-        }
-        writeJsonObjectEnd();
-    }
-
-    /**
-     * Writes the list of <code>Resource</code>s to the JSONGenerator.
-     *
-     * @param resources
-     *            the list of resources to be written.
-     */
-    private void writeResources(List<Resource> resources)
-            throws JsonGenerationException, IOException {
-
-        List<String> resourceStrings = new ArrayList<String>();
-
-        for (Resource resource : resources) {
-            resourceStrings.add(resource.getId());
-        }
-        writeJsonArray(JsonDocumentFields.RESOURCE, resourceStrings);
-    }
-
-    /**
-     * Writes the list of <code>Action</code>s to the JSONGenerator.
-     *
-     * @param actions
-     *            the list of the actions to be written.
-     */
-    private void writeActions(List<Action> actions)
-            throws JsonGenerationException, IOException {
-        List<String> actionStrings = new ArrayList<String>();
-
-        for (Action action : actions) {
-            actionStrings.add(action.getActionName());
-        }
-        writeJsonArray(JsonDocumentFields.ACTION, actionStrings);
-    }
-
-    /**
-     * Writes the list of <code>Principal</code>s to the JSONGenerator.
-     *
-     * @param principals
-     *            the list of principals to be written.
-     */
-    private void writePrincipals(List<Principal> principals)
-            throws JsonGenerationException, IOException {
-        if (principals.size() == 1 && principals.get(0).equals(Principal.All)) {
-            writeJsonKeyValue(JsonDocumentFields.PRINCIPAL, Principal.All.getId());
-        } else {
-            writeJsonObjectStart(JsonDocumentFields.PRINCIPAL);
-
-            Map<String, List<String>> principalsByScheme = groupPrincipalByScheme(principals);
-
-            List<String> principalValues;
-            for (Map.Entry<String, List<String>> entry : principalsByScheme.entrySet()) {
-                principalValues = principalsByScheme.get(entry.getKey());
-
-                if (principalValues.size() == 1) {
-                    writeJsonKeyValue(entry.getKey(), principalValues.get(0));
-                } else {
-                    writeJsonArray(entry.getKey(), principalValues);
-                }
-
-            }
-            writeJsonObjectEnd();
-        }
-    }
-
-    /**
-     * Groups the list of <code>Principal</code>s by the Scheme.
-     *
-     * @param principals
-     *            the list of <code>Principal</code>s
-     * @return a map grouped by scheme of the principal.
-     */
-    private Map<String, List<String>> groupPrincipalByScheme(
-            List<Principal> principals) {
-        Map<String, List<String>> principalsByScheme = new LinkedHashMap<String, List<String>>();
-
-        String provider;
-        List<String> principalValues;
-        for (Principal principal : principals) {
-            provider = principal.getProvider();
-            if (!principalsByScheme.containsKey(provider)) {
-                principalsByScheme.put(provider, new ArrayList<String>());
-            }
-            principalValues = principalsByScheme.get(provider);
-            principalValues.add(principal.getId());
-        }
-
-        return principalsByScheme;
-    }
-
-    /**
-     * Inner class to hold condition values for each key under a condition type.
-     */
-    static class ConditionsByKey {
-        private Map<String,List<String>> conditionsByKey;
-
-        public ConditionsByKey(){
-            conditionsByKey = new LinkedHashMap<String,List<String>>();
-        }
-
-        public Map<String,List<String>> getConditionsByKey() {
-            return conditionsByKey;
-        }
-
-        public void setConditionsByKey(Map<String,List<String>> conditionsByKey) {
-            this.conditionsByKey = conditionsByKey;
-        }
-
-        public boolean containsKey(String key){
-            return conditionsByKey.containsKey(key);
-        }
-
-        public List<String> getConditionsByKey(String key){
-            return conditionsByKey.get(key);
-        }
-
-        public Set<String> keySet(){
-            return conditionsByKey.keySet();
-        }
-
-        public void addValuesToKey(String key, List<String> values) {
-
-            List<String> conditionValues = getConditionsByKey(key);
-            if (conditionValues == null)
-                conditionsByKey.put(key, new ArrayList<String>(values));
-            else
-                conditionValues.addAll(values);
-        }
-    }
-
-    /**
-     * Groups the list of <code>Condition</code>s by the condition type and
-     * condition key.
-     *
-     * @param conditions
-     *            the list of conditions to be grouped
-     * @return a map of conditions grouped by type and then key.
-     */
-    private Map<String, ConditionsByKey> groupConditionsByTypeAndKey(
-            List<Condition> conditions) {
-        Map<String, ConditionsByKey> conditionsByType = new LinkedHashMap<String, ConditionsByKey>();
-
-        String type;
-        String key;
-        ConditionsByKey conditionsByKey;
-        for (Condition condition : conditions) {
-            type = condition.getType();
-            key = condition.getConditionKey();
-
-            if (!(conditionsByType.containsKey(type))) {
-                conditionsByType.put(type, new ConditionsByKey());
-            }
-
-            conditionsByKey = conditionsByType.get(type);
-            conditionsByKey.addValuesToKey(key, condition.getValues());
-        }
-        return conditionsByType;
-    }
-
-    /**
-     * Writes an array along with its values to the JSONGenerator.
-     *
-     * @param arrayName
-     *            name of the JSON array.
-     * @param values
-     *            values of the JSON array.
-     */
-    private void writeJsonArray(String arrayName, List<String> values)
-            throws JsonGenerationException, IOException {
-        writeJsonArrayStart(arrayName);
-        for (String value : values)
-            generator.writeString(value);
-        writeJsonArrayEnd();
-    }
-
-    /**
-     * Writes the Start of Object String to the JSONGenerator along with Object
-     * Name.
-     *
-     * @param fieldName
-     *            name of the JSON Object.
-     */
-    private void writeJsonObjectStart(String fieldName)
-            throws JsonGenerationException, IOException {
-        generator.writeObjectFieldStart(fieldName);
-    }
-
-    /**
-     * Writes the End of Object String to the JSONGenerator.
-     */
-    private void writeJsonObjectEnd() throws JsonGenerationException, IOException {
-        generator.writeEndObject();
-    }
-
-    /**
-     * Writes the Start of Array String to the JSONGenerator along with Array
-     * Name.
-     *
-     * @param fieldName
-     *            name of the JSON array
-     */
-    private void writeJsonArrayStart(String fieldName)
-            throws JsonGenerationException, IOException {
-        generator.writeArrayFieldStart(fieldName);
-    }
-
-    /**
-     * Writes the End of Array String to the JSONGenerator.
-     */
-    private void writeJsonArrayEnd() throws JsonGenerationException, IOException {
-        generator.writeEndArray();
-    }
-
-    /**
-     * Writes the given field and the value to the JsonGenerator
-     *
-     * @param fieldName
-     *            the JSON field name
-     * @param value
-     *            value for the field
-     */
-    private void writeJsonKeyValue(String fieldName, String value)
-            throws JsonGenerationException, IOException {
-        generator.writeStringField(fieldName, value);
-    }
-
-    /**
-     * Checks if the given object is not null.
-     *
-     * @param object
-     *            the object compared to null.
-     * @return true if the object is not null else false
-     */
-    private boolean isNotNull(Object object) {
-        return null != object;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/package-info.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/package-info.java
--- ./src/main/java/com/amazonaws/auth/policy/package-info.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/package-info.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-/**
- * Classes for creating custom AWS access control policies.  Policies allow you to specify fine grained
- * access controls on your AWS resources.  You can allow or deny access to your AWS resources based on:
- * <ul>
- *   <li>what <b>resource</b> is being accessed
- *   <li>who is accessing the resource (i.e. the <b>principal</b>)
- *   <li>what <b>action</b> is being taken on the resource
- *   <li>a variety of <b>conditions</b> including date restrictions, IP address restrictions, etc.
- * </ul>
- *
- * <p>
- * Access control policies are a collection of statements.
- * Each statement takes the form:  "A has permission to do B to C where D applies".
- * <ul>
- *   <li>A is the <b>principal</b> - the AWS account that is making a request to
- *       access or modify one of your AWS resources.
- *   <li>B is the <b>action</b> - the way in which your AWS resource is being accessed or modified, such
- *       as sending a message to an Amazon SQS queue, or storing an object in an Amazon S3 bucket.
- *   <li>C is the <b>resource</b> - your AWS entity that the principal wants to access, such
- *       as an Amazon SQS queue, or an object stored in Amazon S3.
- *   <li>D is the set of <b>conditions</b> - optional constraints that specify when to allow or deny
- *       access for the principal to access your resource.  Many expressive conditions are available,
- *       some specific to each service.  For example you can use date conditions to allow access to
- *       your resources only after or before a specific time.
- * </ul>
- *
- * <p>
- * The following code creates a policy to allow a specific AWS account to send
- * and receive messages using one of your Amazon SQS queues:
- * <pre class="brush: java">
- *    Policy policy = new Policy("MyQueuePolicy");
- *    policy.withStatements(new Statement(Effect.Allow)
- *           .withPrincipals(new Principal("123456789012"))
- *           .withActions(SQSActions.SendMessage, SQSActions.ReceiveMessage)
- *           .withResources(new SQSQueueResource("987654321000", "queue2")));
- * </pre>
- *
- * <p>
- * Once you've created a policy, you need to use methods on the service to upload your policy to AWS.
- */
-package com.amazonaws.auth.policy;
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/Policy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Policy.java
--- ./src/main/java/com/amazonaws/auth/policy/Policy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Policy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,268 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy;
-
-import com.amazonaws.auth.policy.internal.JsonPolicyReader;
-import com.amazonaws.auth.policy.internal.JsonPolicyWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * An AWS access control policy is a object that acts as a container for one or
- * more statements, which specify fine grained rules for allowing or denying
- * various types of actions from being performed on your AWS resources.
- * <p>
- * By default, all requests to use your resource coming from anyone but you are
- * denied. Access control polices can override that by allowing different types
- * of access to your resources, or by explicitly denying different types of
- * access.
- * <p>
- * Each statement in an AWS access control policy takes the form:
- * "A has permission to do B to C where D applies".
- * <ul>
- *   <li>A is the <b>principal</b> - the AWS account that is making a request to
- *       access or modify one of your AWS resources.
- *   <li>B is the <b>action</b> - the way in which your AWS resource is being accessed or modified, such
- *       as sending a message to an Amazon SQS queue, or storing an object in an Amazon S3 bucket.
- *   <li>C is the <b>resource</b> - your AWS entity that the principal wants to access, such
- *       as an Amazon SQS queue, or an object stored in Amazon S3.
- *   <li>D is the set of <b>conditions</b> - optional constraints that specify when to allow or deny
- *       access for the principal to access your resource.  Many expressive conditions are available,
- *       some specific to each service.  For example you can use date conditions to allow access to
- *       your resources only after or before a specific time.
- * </ul>
- * <p>
- * Note that an AWS access control policy should not be confused with the
- * similarly named "POST form policy" concept used in Amazon S3.
- */
-public class Policy {
-
-    /** The default policy version */
-    private static final String DEFAULT_POLICY_VERSION = "2012-10-17";
-
-    private String id;
-    private String version = DEFAULT_POLICY_VERSION;
-    private List<Statement> statements = new ArrayList<Statement>();
-
-    /**
-     * Constructs an empty AWS access control policy ready to be populated with
-     * statements.
-     */
-    public Policy() {}
-
-    /**
-     * Constructs a new AWS access control policy with the specified policy ID.
-     * The policy ID is a user specified string that serves to help developers
-     * keep track of multiple polices. Policy IDs are often used as a human
-     * readable name for a policy.
-     *
-     * @param id
-     *            The policy ID for the new policy object. Policy IDs serve to
-     *            help developers keep track of multiple policies, and are often
-     *            used to give the policy a meaningful, human readable name.
-     */
-    public Policy(String id) {
-        this.id = id;
-    }
-
-    /**
-     * Constructs a new AWS access control policy with the specified policy ID
-     * and collection of statements. The policy ID is a user specified string
-     * that serves to help developers keep track of multiple polices. Policy IDs
-     * are often used as a human readable name for a policy.
-     * <p>
-     * Any statements that don't have a statement ID yet will automatically be
-     * assigned a unique ID within this policy.
-     *
-     * @param id
-     *            The policy ID for the new policy object. Policy IDs serve to
-     *            help developers keep track of multiple policies, and are often
-     *            used to give the policy a meaningful, human readable name.
-     * @param statements
-     *            The statements to include in the new policy.
-     */
-    public Policy(String id, Collection<Statement> statements) {
-        this(id);
-        setStatements(statements);
-    }
-
-    /**
-     * Returns the policy ID for this policy. Policy IDs serve to help
-     * developers keep track of multiple policies, and are often used as human
-     * readable name for a policy.
-     *
-     * @return The policy ID for this policy.
-     */
-    public String getId() {
-        return id;
-    }
-
-    /**
-     * Sets the policy ID for this policy. Policy IDs serve to help developers
-     * keep track of multiple policies, and are often used as human readable
-     * name for a policy.
-     *
-     * @param id
-     *            The policy ID for this policy.
-     */
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    /**
-     * Sets the policy ID for this policy and returns the updated policy so that
-     * multiple calls can be chained together.
-     * <p>
-     * Policy IDs serve to help developers keep track of multiple policies, and
-     * are often used as human readable name for a policy.
-     *
-     * @param id
-     *            The policy ID for this policy.
-     *
-     * @return The updated Policy object so that additional calls can be chained
-     *         together.
-     */
-    public Policy withId(String id) {
-        setId(id);
-        return this;
-    }
-
-    /**
-     * Returns the version of this AWS policy.
-     *
-     * @return The version of this AWS policy.
-     */
-    public String getVersion() {
-        return version;
-    }
-
-    /**
-     * Returns the collection of statements contained by this policy. Individual
-     * statements in a policy are what specify the rules that enable or disable
-     * access to your AWS resources.
-     *
-     * @return The collection of statements contained by this policy.
-     */
-    public Collection<Statement> getStatements() {
-        return statements;
-    }
-
-    /**
-     * Sets the collection of statements contained by this policy. Individual
-     * statements in a policy are what specify the rules that enable or disable
-     * access to your AWS resources.
-     * <p>
-     * Any statements that don't have a statement ID yet will automatically be
-     * assigned a unique ID within this policy.
-     *
-     * @param statements
-     *            The collection of statements included in this policy.
-     */
-    public void setStatements(Collection<Statement> statements) {
-        this.statements = new ArrayList<Statement>(statements);
-        assignUniqueStatementIds();
-    }
-
-    /**
-     * Sets the collection of statements contained by this policy and returns
-     * this policy object so that additional method calls can be chained
-     * together.
-     * <p>
-     * Individual statements in a policy are what specify the rules that enable
-     * or disable access to your AWS resources.
-     * <p>
-     * Any statements that don't have a statement ID yet will automatically be
-     * assigned a unique ID within this policy.
-     *
-     * @param statements
-     *            The collection of statements included in this policy.
-     *
-     * @return The updated policy object, so that additional method calls can be
-     *         chained together.
-     */
-    public Policy withStatements(Statement... statements) {
-        setStatements(Arrays.asList(statements));
-        return this;
-    }
-
-    /**
-     * Returns a JSON string representation of this AWS access control policy,
-     * suitable to be sent to an AWS service as part of a request to set an
-     * access control policy.
-     *
-     * @return A JSON string representation of this AWS access control policy.
-     */
-    public String toJson() {
-        return new JsonPolicyWriter().writePolicyToString(this);
-    }
-
-    /**
-     * Returns an AWS access control policy object generated from JSON string. This will automatically strip all dashes from
-     * AWS principal IDs, because AWS account IDs must not contain dashes. If this behavior isn't desirable (eg. because you are
-     * using IAM AWS principal IDs with dashes in the name), you may disable this behavior by specifying custom JSON policy reader
-     * options in {@link #fromJson(String, PolicyReaderOptions)}.
-     *
-     * @param jsonString
-     *            The JSON string representation of this AWS access control policy.
-     *
-     * @return An AWS access control policy object.
-     *
-     * @throws IllegalArgumentException
-     *      If the specified JSON string is null or invalid and cannot be
-     *      converted to an AWS policy object.
-     */
-    public static Policy fromJson(String jsonString) {
-        return fromJson(jsonString, new PolicyReaderOptions());
-    }
-
-    /**
-     * Returns an AWS access control policy object generated from JSON string. Allows configuring options for the JSON policy
-     * reader (for example, to disable the stripping of dashes in the principal ID).
-     *
-     * @param jsonString
-     *            The JSON string representation of this AWS access control policy.
-     * @param options
-     *            Configuration for the JSON policy reader that affects the way in which it converts the JSON configuration.
-     *
-     * @return An AWS access control policy object.
-     *
-     * @throws IllegalArgumentException
-     *      If the specified JSON string is null or invalid and cannot be
-     *      converted to an AWS policy object.
-     */
-    public static Policy fromJson(String jsonString, PolicyReaderOptions options) {
-        return new JsonPolicyReader(options).createPolicyFromJsonString(jsonString);
-    }
-
-    private void assignUniqueStatementIds() {
-        Set<String> usedStatementIds = new HashSet<String>();
-        for (Statement statement : statements) {
-            if (statement.getId() != null) usedStatementIds.add(statement.getId());
-        }
-
-        int counter = 0;
-        for (Statement statement : statements) {
-            if (statement.getId() != null) continue;
-
-            while (usedStatementIds.contains(Integer.toString(++counter)));
-            statement.setId(Integer.toString(counter));
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/PolicyReaderOptions.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/PolicyReaderOptions.java
--- ./src/main/java/com/amazonaws/auth/policy/PolicyReaderOptions.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/PolicyReaderOptions.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.auth.policy;
-
-/**
- * Options that affect the way in which {@link Policy#fromJson(String, PolicyReaderOptions)} will generate a Policy.
- */
-public class PolicyReaderOptions {
-    private boolean stripAwsPrincipalIdHyphensEnabled = true;
-
-    /**
-     * Whether AWS account IDs should have hyphens removed in their name.
-     */
-    public boolean isStripAwsPrincipalIdHyphensEnabled() {
-        return stripAwsPrincipalIdHyphensEnabled;
-    }
-
-    /**
-     * Configure whether hyphens should be stripped from the AWS principal IDs that are read from the JSON-formatted
-     * policy document. This is useful because AWS account IDs must be specified without hyphens, but the user may not be
-     * aware that hyphens should not be used when configuring their policy.
-     *
-     * This behavior may be undesirable when using IAM AWS principal IDs, which may contain hyphens. In that case, this
-     * option may be explicitly disabled. If this is set to false, you must remove hyphens from your AWS principal IDs
-     * manually.
-     *
-     * By default, this is enabled (true).
-     */
-    public void setStripAwsPrincipalIdHyphensEnabled(boolean stripAwsPrincipalIdHyphensEnabled) {
-        this.stripAwsPrincipalIdHyphensEnabled = stripAwsPrincipalIdHyphensEnabled;
-    }
-
-    /**
-     * Fluent-style setter for {@link #setStripAwsPrincipalIdHyphensEnabled(boolean)} that returns "this" for chaining.
-     */
-    public PolicyReaderOptions withStripAwsPrincipalIdHyphensEnabled(boolean stripAwsPrincipalIdHyphensEnabled) {
-        setStripAwsPrincipalIdHyphensEnabled(stripAwsPrincipalIdHyphensEnabled);
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/Principal.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Principal.java
--- ./src/main/java/com/amazonaws/auth/policy/Principal.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Principal.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,268 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy;
-
-/**
- * A principal is an AWS account or AWS web serivce, which is being allowed or denied access to a
- * resource through an access control policy. The principal is a property of the
- * {@link Statement} object, not directly the {@link Policy} object.
- * <p>
- * The principal is A in the statement
- * "A has permission to do B to C where D applies."
- * <p>
- * In an access control policy statement, you can set the principal to all
- * authenticated AWS users through the {@link Principal#AllUsers} member. This
- * is useful when you don't want to restrict access based on the identity of the
- * requester, but instead on other identifying characteristics such as the
- * requester's IP address.
- */
-public class Principal {
-
-    /**
-     * Principal instance that includes all users, including anonymous users.
-     * <p>
-     * This is useful when you don't want to restrict access based on the
-     * identity of the requester, but instead on other identifying
-     * characteristics such as the requester's IP address.
-     */
-    public static final Principal AllUsers = new Principal("AWS", "*");
-
-    /**
-     * Principal instance that includes all AWS web services.
-     */
-    public static final Principal AllServices = new Principal("Service", "*");
-
-    /**
-     * Principal instance that includes all the web identity providers.
-     */
-    public static final Principal AllWebProviders = new Principal("Federated", "*");
-
-    /**
-     * Principal instance that includes all the AWS accounts, AWS web services and web identity providers.
-     */
-    public static final Principal All = new Principal("*", "*");
-
-    private final String id;
-    private final String provider;
-
-    /**
-     * Constructs a new principal with the specified AWS web service which
-     * is being allowed or denied access to a resource through an access control
-     * policy.
-     *
-     * @param service
-     *            An AWS service.
-     */
-    public Principal(Services service) {
-        if (service == null) {
-            throw new IllegalArgumentException("Null AWS service name specified");
-        }
-       id = service.getServiceId();
-       provider = "Service";
-    }
-
-
-    /**
-     * Constructs a new principal with the specified AWS account ID. This method
-     * automatically strips hyphen characters found in the account Id.
-     *
-     * @param accountId
-     *            An AWS account ID.
-     */
-    public Principal(String accountId) {
-        this("AWS", accountId);
-
-        if (accountId == null) {
-            throw new IllegalArgumentException("Null AWS account ID specified");
-        }
-    }
-
-    /**
-     * Constructs a new principal with the specified id and provider. This
-     * method automatically strips hyphen characters found in the account ID if
-     * the provider is "AWS".
-     */
-    public Principal(String provider, String id) {
-        this(provider, id, provider.equals("AWS"));
-    }
-
-    /**
-     * Constructs a new principal with the specified id and provider. This
-     * method optionally strips hyphen characters found in the account Id.
-     */
-    public Principal(String provider, String id, boolean stripHyphen) {
-        this.provider = provider;
-        this.id = stripHyphen ?
-                id.replace("-", "") : id;
-    }
-
-    /**
-     * Constructs a new principal with the specified web identity provider.
-     *
-     * @param webIdentityProvider
-     *            An web identity provider.
-     */
-    public Principal(WebIdentityProviders webIdentityProvider) {
-        if (webIdentityProvider == null) {
-            throw new IllegalArgumentException("Null web identity provider specified");
-        }
-        this.id = webIdentityProvider.getWebIdentityProvider();
-        provider = "Federated";
-    }
-
-    /**
-     * Returns the provider for this principal, which indicates in what group of
-     * users this principal resides.
-     *
-     * @return The provider for this principal.
-     */
-    public String getProvider() {
-       return provider;
-    }
-
-    /**
-     * Returns the unique ID for this principal.
-     *
-     * @return The unique ID for this principal.
-     */
-    public String getId() {
-            return id;
-    }
-
-    /**
-     * The services who have the right to do the assume the role
-     * action. The AssumeRole action returns a set of temporary security
-     * credentials that you can use to access resources that are defined in the
-     * role's policy. The returned credentials consist of an Access Key ID, a
-     * Secret Access Key, and a security token.
-     */
-    static public enum Services {
-        
-        AmazonApiGateway("apigateway.amazonaws.com"),
-        AWSDataPipeline("datapipeline.amazonaws.com"),
-        AmazonElasticTranscoder("elastictranscoder.amazonaws.com"),
-        AmazonEC2("ec2.amazonaws.com"),
-        AWSOpsWorks("opsworks.amazonaws.com"),
-        AWSCloudHSM("cloudhsm.amazonaws.com"),
-        AllServices("*");
-        private String serviceId;
-
-        /**
-         * The service which has the right to assume the role.
-         */
-        private Services(String serviceId) {
-            this.serviceId = serviceId;
-        }
-
-        public String getServiceId() {
-            return serviceId;
-        }
-
-        /**
-         * Construct the Services object from a string representing the service id.
-         */
-        public static Services fromString(String serviceId) {
-            if (serviceId != null) {
-                for (Services s : Services.values()) {
-                    if (s.getServiceId().equalsIgnoreCase(serviceId)) {
-                        return s;
-                    }
-                }
-            }
-
-            return null;
-        }
-
-
-    }
-
-    /**
-     * Web identity providers, such as Login with Amazon, Facebook, or Google.
-     */
-    static public enum WebIdentityProviders {
-
-        Facebook("graph.facebook.com"),
-        Google("accounts.google.com"),
-        Amazon("www.amazon.com"),
-        AllProviders("*");
-
-        private String webIdentityProvider;
-
-        /**
-         * The web identity provider which has the right to assume the role.
-         */
-        private WebIdentityProviders(String webIdentityProvider) {
-            this.webIdentityProvider = webIdentityProvider;
-        }
-
-        public String getWebIdentityProvider() {
-            return webIdentityProvider;
-        }
-
-        /**
-         * Construct the Services object from a string representing web identity provider.
-         */
-        public static WebIdentityProviders fromString(String webIdentityProvider) {
-            if (webIdentityProvider != null) {
-                for (WebIdentityProviders provider : WebIdentityProviders.values()) {
-                    if (provider.getWebIdentityProvider().equalsIgnoreCase(webIdentityProvider)) {
-                        return provider;
-                    }
-                }
-            }
-
-            return null;
-        }
-
-
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int hashCode = 1;
-
-        hashCode = prime * hashCode + provider.hashCode();
-        hashCode = prime * hashCode + id.hashCode();
-        return hashCode;
-    }
-
-    @Override
-    public boolean equals(Object principal) {
-        if (this == principal) {
-            return true;
-        }
-
-        if (principal == null) {
-            return false;
-        }
-
-        if (principal instanceof Principal == false) {
-            return false;
-        }
-
-        Principal other = (Principal) principal;
-
-        if (this.getProvider().equals(other.getProvider())
-                && this.getId().equals(other.getId())) {
-            return true;
-        }
-
-        return false;
-    }
-
-
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/Resource.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Resource.java
--- ./src/main/java/com/amazonaws/auth/policy/Resource.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Resource.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,74 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy;
-
-/**
- * Represents a resource involved in an AWS access control policy statement.
- * Resources are the service specific AWS entities owned by your account. Amazon
- * SQS queues, Amazon S3 buckets and objects, and Amazon SNS topics are all
- * examples of AWS resources.
- * <p>
- * The standard way of specifying an AWS resource is with an Amazon Resource
- * Name (ARN).
- * <p>
- * The resource is C in the statement
- * "A has permission to do B to C where D applies."
- */
-public class Resource {
-    private final String resource;
-
-    /**
-     * Constructs a new AWS access control policy resource. Resources are
-     * typically specified as Amazon Resource Names (ARNs).
-     * <p>
-     * You specify the resource using the following Amazon Resource Name (ARN)
-     * format:
-     * <b>arn:aws:&lt;vendor>:&lt;region>:&lt;namespace>:&lt;relative-id></b>
-     * <p>
-     * <ul>
-     * <li>vendor identifies the AWS product (e.g., sns)</li>
-     * <li>region is the AWS Region the resource resides in (e.g., us-east-1),
-     * if any
-     * <li>namespace is the AWS account ID with no hyphens (e.g., 123456789012)
-     * <li>relative-id is the service specific portion that identifies the
-     * specific resource
-     * </ul>
-     * <p>
-     * For example, an Amazon SQS queue might be addressed with the following
-     * ARN: <b>arn:aws:sqs:us-east-1:987654321000:MyQueue</b>
-     * <p>
-     * Some resources may not use every field in an ARN. For example, resources
-     * in Amazon S3 are global, so they omit the region field:
-     * <b>arn:aws:s3:::bucket/*</b>
-     *
-     * @param resource
-     *            The Amazon Resource Name (ARN) uniquely identifying the
-     *            desired AWS resource.
-     */
-    public Resource(String resource) {
-        this.resource = resource;
-    }
-
-    /**
-     * Returns the resource ID, typically an Amazon Resource Name (ARN),
-     * identifying this resource.
-     *
-     * @return The resource ID, typically an Amazon Resource Name (ARN),
-     *         identifying this resource.
-     */
-    public String getId() {
-        return resource;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/resources/package-info.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/resources/package-info.java
--- ./src/main/java/com/amazonaws/auth/policy/resources/package-info.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/resources/package-info.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,22 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-/**
- * Collection of resources for AWS access control policies.  Resources describe
- * what AWS entities are being accessed or modified when an AWS access control policy
- * is evaluated for an incoming request.  Amazon SQS queues, Amazon SNS topics, and
- * Amazon S3 buckets and objects are all examples of AWS resources.
- */
-package com.amazonaws.auth.policy.resources;
diff -Nau8r ./src/main/java/com/amazonaws/auth/policy/Statement.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Statement.java
--- ./src/main/java/com/amazonaws/auth/policy/Statement.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/policy/Statement.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,412 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.policy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * A statement is the formal description of a single permission, and is always
- * contained within a policy object.
- * <p>
- * A statement describes a rule for allowing or denying access to a specific AWS
- * resource based on how the resource is being accessed, and who is attempting
- * to access the resource. Statements can also optionally contain a list of
- * conditions that specify when a statement is to be honored.
- * <p>
- * For example, consider a statement that:
- * <ul>
- * <li>allows access (the effect)
- * <li>for a list of specific AWS account IDs (the principals)
- * <li>when accessing an SQS queue (the resource)
- * <li>using the SendMessage operation (the action)
- * <li>and the request occurs before a specific date (a condition)
- * </ul>
- *
- * <p>
- * Statements takes the form:  "A has permission to do B to C where D applies".
- * <ul>
- *   <li>A is the <b>principal</b> - the AWS account that is making a request to
- *       access or modify one of your AWS resources.
- *   <li>B is the <b>action</b> - the way in which your AWS resource is being accessed or modified, such
- *       as sending a message to an Amazon SQS queue, or storing an object in an Amazon S3 bucket.
- *   <li>C is the <b>resource</b> - your AWS entity that the principal wants to access, such
- *       as an Amazon SQS queue, or an object stored in Amazon S3.
- *   <li>D is the set of <b>conditions</b> - optional constraints that specify when to allow or deny
- *       access for the principal to access your resource.  Many expressive conditions are available,
- *       some specific to each service.  For example you can use date conditions to allow access to
- *       your resources only after or before a specific time.
- * </ul>
- *
- * <p>
- * There are many resources and conditions available for use in statements, and
- * you can combine them to form fine grained custom access control polices.
- */
-public class Statement {
-
-    /**
-     * The effect is the result that you want a policy statement to return at
-     * evaluation time. A policy statement can either allow access or explicitly
-     * deny access.
-     */
-    public static enum Effect {
-        Allow(), Deny();
-    }
-
-    private String id;
-    private Effect effect;
-    private List<Principal> principals = new ArrayList<Principal>();
-    private List<Action> actions = new ArrayList<Action>();
-    private List<Resource> resources;
-    private List<Condition> conditions = new ArrayList<Condition>();
-
-    /**
-     * Constructs a new access control policy statement with the specified
-     * effect.
-     * <p>
-     * Before a statement is valid and can be sent to AWS, callers must set the
-     * principals, resources, and actions (as well as any optional conditions)
-     * involved in the statement.
-     *
-     * @param effect
-     *            The effect this statement has (allowing access or denying
-     *            access) when all conditions, resources, principals, and
-     *            actions are matched.
-     */
-    public Statement(Effect effect) {
-        this.effect = effect;
-        this.id = null;
-    }
-
-    /**
-     * Returns the ID for this statement. Statement IDs serve to help keep track
-     * of multiple statements, and are often used to give the statement a
-     * meaningful, human readable name.
-     * <p>
-     * Statement IDs must be unique within a policy, but are not required to be
-     * globally unique.
-     * <p>
-     * If you do not explicitly assign an ID to a statement, a unique ID will be
-     * automatically assigned when the statement is added to a policy.
-     * <p>
-     * Developers should be careful to not use the same statement ID for
-     * multiple statements in the same policy. Reusing the same statement ID in
-     * different policies is not a problem.
-     *
-     * @return The statement ID.
-     */
-    public String getId() {
-        return id;
-    }
-
-    /**
-     * Sets the ID for this statement. Statement IDs serve to help keep track of
-     * multiple statements, and are often used to give the statement a
-     * meaningful, human readable name.
-     * <p>
-     * Statement IDs must be unique within a policy, but are not required to be
-     * globally unique.
-     * <p>
-     * If you do not explicitly assign an ID to a statement, a unique ID will be
-     * automatically assigned when the statement is added to a policy.
-     * <p>
-     * Developers should be careful to not use the same statement ID for
-     * multiple statements in the same policy. Reusing the same statement ID in
-     * different policies is not a problem.
-     *
-     * @param id
-     *            The new statement ID for this statement.
-     */
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    /**
-     * Sets the ID for this statement and returns the updated statement so
-     * multiple calls can be chained together.
-     * <p>
-     * Statement IDs serve to help keep track of multiple statements, and are
-     * often used to give the statement a meaningful, human readable name.
-     * <p>
-     * If you do not explicitly assign an ID to a statement, a unique ID will be
-     * automatically assigned when the statement is added to a policy.
-     * <p>
-     * Developers should be careful to not use the same statement ID for
-     * multiple statements in the same policy. Reusing the same statement ID in
-     * different policies is not a problem.
-     *
-     * @param id
-     *            The new statement ID for this statement.
-     */
-    public Statement withId(String id) {
-        setId(id);
-        return this;
-    }
-
-    /**
-     * Returns the result effect of this policy statement when it is evaluated.
-     * A policy statement can either allow access or explicitly
-     *
-     * @return The result effect of this policy statement.
-     */
-    public Effect getEffect() {
-        return effect;
-    }
-
-    /**
-     * Sets the result effect of this policy statement when it is evaluated. A
-     * policy statement can either allow access or explicitly
-     *
-     * @param effect
-     *            The result effect of this policy statement.
-     */
-    public void setEffect(Effect effect) {
-        this.effect = effect;
-    }
-
-    /**
-     * Returns the list of actions to which this policy statement applies.
-     * Actions limit a policy statement to specific service operations that are
-     * being allowed or denied by the policy statement. For example, you might
-     * want to allow any AWS user to post messages to your SQS queue using the
-     * SendMessage action, but you don't want to allow those users other actions
-     * such as ReceiveMessage or DeleteQueue.
-     *
-     * @return The list of actions to which this policy statement applies.
-     */
-    public List<Action> getActions() {
-        return actions;
-    }
-
-    /**
-     * Sets the list of actions to which this policy statement applies. Actions
-     * limit a policy statement to specific service operations that are being
-     * allowed or denied by the policy statement. For example, you might want to
-     * allow any AWS user to post messages to your SQS queue using the
-     * SendMessage action, but you don't want to allow those users other actions
-     * such as ReceiveMessage or DeleteQueue.
-     *
-     * @param actions
-     *            The list of actions to which this policy statement applies.
-     */
-    public void setActions(Collection<Action> actions) {
-        this.actions = new ArrayList<Action>(actions);
-    }
-
-    /**
-     * Sets the list of actions to which this policy statement applies and
-     * returns this updated Statement object so that additional method calls can
-     * be chained together.
-     * <p>
-     * Actions limit a policy statement to specific service operations that are
-     * being allowed or denied by the policy statement. For example, you might
-     * want to allow any AWS user to post messages to your SQS queue using the
-     * SendMessage action, but you don't want to allow those users other actions
-     * such as ReceiveMessage or DeleteQueue.
-     *
-     * @param actions
-     *            The list of actions to which this statement applies.
-     *
-     * @return The updated Statement object so that additional method calls can
-     *         be chained together.
-     */
-    public Statement withActions(Action... actions) {
-        setActions(Arrays.asList(actions));
-        return this;
-    }
-
-    /**
-     * Returns the resources associated with this policy statement. Resources
-     * are what a policy statement is allowing or denying access to, such as an
-     * Amazon SQS queue or an Amazon SNS topic.
-     * <p>
-     * Note that some services allow only one resource to be specified per
-     * policy statement.
-     *
-     * @return The resources associated with this policy statement.
-     */
-    public List<Resource> getResources() {
-        return resources;
-    }
-
-    /**
-     * Sets the resources associated with this policy statement. Resources are
-     * what a policy statement is allowing or denying access to, such as an
-     * Amazon SQS queue or an Amazon SNS topic.
-     * <p>
-     * Note that some services allow only one resource to be specified per
-     * policy statement.
-     *
-     * @param resources
-     *            The resources associated with this policy statement.
-     */
-    public void setResources(Collection<Resource> resources) {
-        this.resources = new ArrayList<Resource>(resources);
-    }
-
-    /**
-     * Sets the resources associated with this policy statement and returns this
-     * updated Statement object so that additional method calls can be chained
-     * together.
-     * <p>
-     * Resources are what a policy statement is allowing or denying access to,
-     * such as an Amazon SQS queue or an Amazon SNS topic.
-     * <p>
-     * Note that some services allow only one resource to be specified per
-     * policy statement.
-     *
-     * @param resources
-     *            The resources associated with this policy statement.
-     *
-     * @return The updated Statement object so that additional method calls can
-     *         be chained together.
-     */
-    public Statement withResources(Resource... resources) {
-        setResources(Arrays.asList(resources));
-        return this;
-    }
-
-    /**
-     * Returns the conditions associated with this policy statement. Conditions
-     * allow policy statements to be conditionally evaluated based on the many
-     * available condition types.
-     * <p>
-     * For example, a statement that allows access to an Amazon SQS queue could
-     * use a condition to only apply the effect of that statement for requests
-     * that are made before a certain date, or that originate from a range of IP
-     * addresses.
-     * <p>
-     * When multiple conditions are included in a single statement, all
-     * conditions must evaluate to true in order for the statement to take
-     * effect.
-     *
-     * @return The conditions associated with this policy statement.
-     */
-    public List<Condition> getConditions() {
-        return conditions;
-    }
-
-    /**
-     * Sets the conditions associated with this policy statement. Conditions
-     * allow policy statements to be conditionally evaluated based on the many
-     * available condition types.
-     * <p>
-     * For example, a statement that allows access to an Amazon SQS queue could
-     * use a condition to only apply the effect of that statement for requests
-     * that are made before a certain date, or that originate from a range of IP
-     * addresses.
-     * <p>
-     * Multiple conditions can be included in a single statement, and all
-     * conditions must evaluate to true in order for the statement to take
-     * effect.
-     *
-     * @param conditions
-     *            The conditions associated with this policy statement.
-     */
-    public void setConditions(List<Condition> conditions) {
-        this.conditions = conditions;
-    }
-
-    /**
-     * Sets the conditions associated with this policy statement, and returns
-     * this updated Statement object so that additional method calls can be
-     * chained together.
-     * <p>
-     * Conditions allow policy statements to be conditionally evaluated based on
-     * the many available condition types.
-     * <p>
-     * For example, a statement that allows access to an Amazon SQS queue could
-     * use a condition to only apply the effect of that statement for requests
-     * that are made before a certain date, or that originate from a range of IP
-     * addresses.
-     * <p>
-     * Multiple conditions can be included in a single statement, and all
-     * conditions must evaluate to true in order for the statement to take
-     * effect.
-     *
-     * @param conditions
-     *            The conditions associated with this policy statement.
-     *
-     * @return The updated Statement object so that additional method calls can
-     *         be chained together.
-     */
-    public Statement withConditions(Condition... conditions) {
-        setConditions(Arrays.asList(conditions));
-        return this;
-    }
-
-    /**
-     * Returns the principals associated with this policy statement, indicating
-     * which AWS accounts are affected by this policy statement.
-     *
-     * @return The list of principals associated with this policy statement.
-     */
-    public List<Principal> getPrincipals() {
-        return principals;
-    }
-
-    /**
-     * Sets the principals associated with this policy statement, indicating
-     * which AWS accounts are affected by this policy statement.
-     * <p>
-     * If you don't want to restrict your policy to specific users, you can use
-     * {@link Principal#AllUsers} to apply the policy to any user trying to
-     * access your resource.
-     *
-     * @param principals
-     *            The list of principals associated with this policy statement.
-     */
-    public void setPrincipals(Collection<Principal> principals) {
-        this.principals = new ArrayList<Principal>(principals);
-    }
-
-    /**
-     * Sets the principals associated with this policy statement, indicating
-     * which AWS accounts are affected by this policy statement.
-     * <p>
-     * If you don't want to restrict your policy to specific users, you can use
-     * {@link Principal#AllUsers} to apply the policy to any user trying to
-     * access your resource.
-     *
-     * @param principals
-     *            The list of principals associated with this policy statement.
-     */
-    public void setPrincipals(Principal... principals) {
-        setPrincipals(new ArrayList<Principal>(Arrays.asList(principals)));
-    }
-
-    /**
-     * Sets the principals associated with this policy statement, and returns
-     * this updated Statement object. Principals control which AWS accounts are
-     * affected by this policy statement.
-     * <p>
-     * If you don't want to restrict your policy to specific users, you can use
-     * {@link Principal#AllUsers} to apply the policy to any user trying to
-     * access your resource.
-     *
-     * @param principals
-     *            The list of principals associated with this policy statement.
-     *
-     * @return The updated Statement object so that additional method calls can
-     *         be chained together.
-     */
-    public Statement withPrincipals(Principal... principals) {
-        setPrincipals(principals);
-        return this;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/presign/PresignerFacade.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/presign/PresignerFacade.java
--- ./src/main/java/com/amazonaws/auth/presign/PresignerFacade.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/presign/PresignerFacade.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,99 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.presign;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.annotation.Immutable;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.Presigner;
-import com.amazonaws.internal.auth.SignerProvider;
-import com.amazonaws.internal.auth.SignerProviderContext;
-import com.amazonaws.util.CredentialUtils;
-import com.amazonaws.util.RuntimeHttpUtils;
-
-import java.net.URL;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Really thin facade over {@link Presigner} to deal with some common concerns like credential resolution, adding custom headers
- * and query params to be included in signing, and conversion to a usable URL.
- */
-@Immutable
-@SdkProtectedApi
-public final class PresignerFacade {
-
-    private final AWSCredentialsProvider credentialsProvider;
-    private final SignerProvider signerProvider;
-
-    public PresignerFacade(PresignerParams presignerParams) {
-        this.credentialsProvider = presignerParams.credentialsProvider();
-        this.signerProvider = presignerParams.signerProvider();
-    }
-
-    public URL presign(Request<?> request, Date expirationDate) {
-        final Presigner presigner = (Presigner) signerProvider.getSigner(SignerProviderContext.builder()
-                                                                                 .withIsRedirect(false)
-                                                                                 .withRequest(request)
-                                                                                 .withUri(request.getEndpoint())
-                                                                                 .build());
-        if (request.getOriginalRequest() != null) {
-            addCustomQueryParams(request);
-            addCustomHeaders(request);
-        }
-        final AWSCredentialsProvider credentialsProvider = resolveCredentials(request);
-        presigner.presignRequest(request, credentialsProvider.getCredentials(), expirationDate);
-        return RuntimeHttpUtils.convertRequestToUrl(request, true, false);
-    }
-
-    private void addCustomQueryParams(Request<?> request) {
-        final Map<String, List<String>> queryParameters = request.getOriginalRequest().getCustomQueryParameters();
-        if (queryParameters == null || queryParameters.isEmpty()) {
-            return;
-        }
-        for (Map.Entry<String, List<String>> param : queryParameters.entrySet()) {
-            request.addParameters(param.getKey(), param.getValue());
-        }
-    }
-
-    private void addCustomHeaders(Request<?> request) {
-        final Map<String, String> headers = request.getOriginalRequest().getCustomRequestHeaders();
-        if (headers == null || headers.isEmpty()) {
-            return;
-        }
-        for (Map.Entry<String, String> header : headers.entrySet()) {
-            request.addHeader(header.getKey(), header.getValue());
-        }
-    }
-
-    private AWSCredentialsProvider resolveCredentials(Request<?> request) {
-        return CredentialUtils.getCredentialsProvider(request.getOriginalRequest(), this.credentialsProvider);
-    }
-
-    /**
-     * Empty request object useful for setting request level credentials without having the user facing presiging request extend
-     * from {@link AmazonWebServiceRequest}.
-     */
-    public static class PresigningRequest extends AmazonWebServiceRequest {
-
-        public PresigningRequest withRequestCredentialsProvider(AWSCredentialsProvider credentialsProvider) {
-            setRequestCredentialsProvider(credentialsProvider);
-            return this;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/presign/PresignerParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/presign/PresignerParams.java
--- ./src/main/java/com/amazonaws/auth/presign/PresignerParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/presign/PresignerParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,110 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth.presign;
-
-import com.amazonaws.annotation.Immutable;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.SdkClock;
-import com.amazonaws.internal.auth.SignerProvider;
-
-import java.net.URI;
-
-/**
- * Params object passed to the presigner extension class for a service client and also for {@link PresignerFacade}.
- */
-@Immutable
-@SdkProtectedApi
-public class PresignerParams {
-
-    private final URI endpoint;
-    private final AWSCredentialsProvider credentialsProvider;
-    private final SignerProvider signerProvider;
-    private final SdkClock clock;
-
-    public PresignerParams(URI endpoint,
-                           AWSCredentialsProvider credentialsProvider,
-                           SignerProvider signerProvider,
-                           SdkClock clock) {
-        this.endpoint = endpoint;
-        this.credentialsProvider = credentialsProvider;
-        this.signerProvider = signerProvider;
-        this.clock = clock;
-    }
-
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    public URI endpoint() {
-        return endpoint;
-    }
-
-    public AWSCredentialsProvider credentialsProvider() {
-        return credentialsProvider;
-    }
-
-    public SignerProvider signerProvider() {
-        return signerProvider;
-    }
-
-    /**
-     * @return Clock providing the current time in milliseconds.
-     */
-    public SdkClock clock() {
-        return this.clock;
-    }
-
-    public static class Builder {
-
-        private URI endpoint;
-        private AWSCredentialsProvider credentialsProvider;
-        private SignerProvider signerProvider;
-        private SdkClock clock;
-
-        private Builder() {
-        }
-
-        public Builder endpoint(URI endpoint) {
-            this.endpoint = endpoint;
-            return this;
-        }
-
-        public Builder credentialsProvider(AWSCredentialsProvider credentialsProvider) {
-            this.credentialsProvider = credentialsProvider;
-            return this;
-        }
-
-        public Builder signerProvider(SignerProvider signerProvider) {
-            this.signerProvider = signerProvider;
-            return this;
-        }
-
-        @SdkTestInternalApi
-        public Builder clock(SdkClock clock) {
-            this.clock = clock;
-            return this;
-        }
-
-        public PresignerParams build() {
-            return new PresignerParams(endpoint, credentialsProvider, signerProvider, resolveClock());
-        }
-
-        private SdkClock resolveClock() {
-            return clock == null ? SdkClock.STANDARD : clock;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/Presigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/Presigner.java
--- ./src/main/java/com/amazonaws/auth/Presigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/Presigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import java.util.Date;
-
-import com.amazonaws.SignableRequest;
-
-/**
- * A request signer that has special-case logic to presign requests, generating
- * a URL which embeds the signature suitable for hyperlinking.
- */
-public interface Presigner {
-    /**
-     * Signs the request by adding the signature to the URL rather than as a
-     * header. This method is expected to modify the passed-in request to
-     * add the signature.
-     *
-     * @param request      The request to sign.
-     * @param credentials  The credentials to sign it with.
-     * @param expiration   The time when this presigned URL will expire.
-     */
-    public void presignRequest(SignableRequest<?> request,
-                               AWSCredentials credentials,
-                               Date expiration);
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/QueryStringSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/QueryStringSigner.java
--- ./src/main/java/com/amazonaws/auth/QueryStringSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/QueryStringSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,204 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import java.net.URI;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TimeZone;
-import java.util.TreeMap;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.SignableRequest;
-
-/**
- * Signer implementation responsible for signing an AWS query string request
- * according to the various signature versions and hashing algorithms.
- */
-public class QueryStringSigner extends AbstractAWSSigner implements Signer {
-    /** Date override for testing only */
-    private Date overriddenDate;
-
-    /**
-     * This signer will add "Signature" parameter to the request. Default
-     * signature version is "2" and default signing algorithm is "HmacSHA256".
-     *
-     * AWSAccessKeyId SignatureVersion SignatureMethod Timestamp Signature
-     *
-     * @param request
-     *            request to be signed.
-     * @param credentials
-     *            The credentials used to use to sign the request.
-     */
-    public void sign(SignableRequest<?> request, AWSCredentials credentials)
-            throws SdkClientException {
-        sign(request, SignatureVersion.V2, SigningAlgorithm.HmacSHA256, credentials);
-    }
-
-    /**
-     * This signer will add following authentication parameters to the request:
-     *
-     * AWSAccessKeyId SignatureVersion SignatureMethod Timestamp Signature
-     *
-     * @param request
-     *            request to be signed.
-     *
-     * @param version
-     *            signature version. "2" is recommended.
-     *
-     * @param algorithm
-     *            signature algorithm. "HmacSHA256" is recommended.
-     */
-    public void sign(SignableRequest<?> request, SignatureVersion version,
-            SigningAlgorithm algorithm, AWSCredentials credentials)
-            throws SdkClientException {
-        // annonymous credentials, don't sign
-        if ( credentials instanceof AnonymousAWSCredentials ) {
-            return;
-        }
-
-        AWSCredentials sanitizedCredentials = sanitizeCredentials(credentials);
-        request.addParameter("AWSAccessKeyId", sanitizedCredentials.getAWSAccessKeyId());
-        request.addParameter("SignatureVersion", version.toString());
-
-        int timeOffset = request.getTimeOffset();
-        request.addParameter("Timestamp", getFormattedTimestamp(timeOffset));
-
-        if ( sanitizedCredentials instanceof AWSSessionCredentials ) {
-            addSessionCredentials(request, (AWSSessionCredentials) sanitizedCredentials);
-        }
-
-        String stringToSign = null;
-        if ( version.equals( SignatureVersion.V1 ) ) {
-            stringToSign = calculateStringToSignV1(request.getParameters());
-        } else if ( version.equals( SignatureVersion.V2 ) ) {
-            request.addParameter("SignatureMethod", algorithm.toString());
-            stringToSign = calculateStringToSignV2(request);
-        } else {
-            throw new SdkClientException("Invalid Signature Version specified");
-        }
-
-        String signatureValue = signAndBase64Encode(stringToSign,
-                sanitizedCredentials.getAWSSecretKey(), algorithm);
-        request.addParameter("Signature", signatureValue);
-    }
-
-    /**
-     * Calculates string to sign for signature version 1.
-     *
-     * @param parameters
-     *            request parameters
-     *
-     * @return String to sign
-     */
-    private String calculateStringToSignV1(Map<String, List<String>> parameters) {
-        StringBuilder data = new StringBuilder();
-        SortedMap<String, List<String>> sorted =
-            new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
-        sorted.putAll(parameters);
-
-        for (Map.Entry<String, List<String>> entry : sorted.entrySet()) {
-            for (String value : entry.getValue()) {
-                data.append(entry.getKey())
-                    .append(value);
-            }
-        }
-
-        return data.toString();
-    }
-
-    /**
-     * Calculate string to sign for signature version 2.
-     *
-     * @param request
-     *            The request being signed.
-     *
-     * @return String to sign
-     *
-     * @throws SdkClientException
-     *             If the string to sign cannot be calculated.
-     */
-    private String calculateStringToSignV2(SignableRequest<?> request) throws SdkClientException {
-        URI endpoint = request.getEndpoint();
-
-        StringBuilder data = new StringBuilder();
-        data.append("POST")
-            .append("\n")
-            .append(getCanonicalizedEndpoint(endpoint))
-            .append("\n")
-            .append(getCanonicalizedResourcePath(request))
-            .append("\n")
-            .append(getCanonicalizedQueryString(request.getParameters()));
-        return data.toString();
-    }
-
-    private String getCanonicalizedResourcePath(SignableRequest<?> request) {
-        String resourcePath = "";
-
-        if (request.getEndpoint().getPath() != null) {
-            resourcePath += request.getEndpoint().getPath();
-        }
-
-        if (request.getResourcePath() != null) {
-            if (resourcePath.length() > 0 &&
-                !resourcePath.endsWith("/") &&
-                !request.getResourcePath().startsWith("/")) {
-                resourcePath += "/";
-            }
-
-            resourcePath += request.getResourcePath();
-        } else if (!resourcePath.endsWith("/")) {
-            resourcePath += "/";
-        }
-
-        if (!resourcePath.startsWith("/")) {
-            resourcePath = "/" + resourcePath;
-        }
-
-        if (resourcePath.startsWith("//")) {
-            resourcePath = resourcePath.substring(1);
-        }
-
-        return resourcePath;
-    }
-
-    /**
-     * Formats date as ISO 8601 timestamp
-     */
-    private String getFormattedTimestamp(int offset) {
-        SimpleDateFormat df = new SimpleDateFormat(
-                "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
-        df.setTimeZone(TimeZone.getTimeZone("UTC"));
-
-        if (overriddenDate != null) {
-            return df.format(overriddenDate);
-        } else {
-            return df.format(getSignatureDate(offset));
-        }
-    }
-
-    /** For testing purposes only, to control the date used in signing. */
-    void overrideDate(Date date) {
-        this.overriddenDate = date;
-    }
-
-    @Override
-    protected void addSessionCredentials(SignableRequest<?> request, AWSSessionCredentials credentials) {
-        request.addParameter("SecurityToken", credentials.getSessionToken());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/RegionAwareSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/RegionAwareSigner.java
--- ./src/main/java/com/amazonaws/auth/RegionAwareSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/RegionAwareSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-/**
- * A signer that needs to know which region it is talking to.
- */
-public interface RegionAwareSigner extends Signer {
-    /**
-     * Configure this signer with the name of the region it will be used
-     * to sign requests for.
-     *
-     * @param value   The name of the region.
-     */
-    void setRegionName(String value);
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/RequestSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/RequestSigner.java
--- ./src/main/java/com/amazonaws/auth/RequestSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/RequestSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *   http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws.auth;
-
-
-import com.amazonaws.SignableRequest;
-
-/**
- * A strategy for applying cryptographic signatures to a request, proving
- * that the request was made by someone in posession of the given set of
- * credentials without transmitting the secret key over the wire.
- */
-
-public interface RequestSigner {
-
-    /**
-     * Sign the given request - modifies the
-     * passed-in request to apply the signature.
-     *
-     * @param request      The request to sign.
-     */
-    void sign(SignableRequest<?> request);
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SdkClock.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SdkClock.java
--- ./src/main/java/com/amazonaws/auth/SdkClock.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SdkClock.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,89 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import java.util.Date;
-
-/**
- * Clock interface to prevent static coupling to {@link System#currentTimeMillis()}.
- */
-@SdkProtectedApi
-public interface SdkClock {
-
-    /**
-     * Standard implementation that calls out to {@link System#currentTimeMillis()}. Used in production code.
-     */
-    SdkClock STANDARD = new SdkClock() {
-        @Override
-        public long currentTimeMillis() {
-            return System.currentTimeMillis();
-        }
-    };
-
-    long currentTimeMillis();
-
-    /**
-     * Mock implementation used in tests.
-     */
-    final class MockClock implements SdkClock {
-        private final long mockedTime;
-
-        public MockClock(Date mockedTime) {
-            this(mockedTime.getTime());
-        }
-
-        public MockClock(long mockedTime) {
-            this.mockedTime = mockedTime;
-        }
-
-        @Override
-        public long currentTimeMillis() {
-            return mockedTime;
-        }
-    }
-
-    /**
-     * Container for Singleton instance of the {@link SdkClock}.
-     */
-    final class Instance {
-
-        private static SdkClock clock = STANDARD;
-
-        public static SdkClock get() {
-            return clock;
-        }
-
-        /**
-         * Should only be used by tests to mock the clock.
-         *
-         * @param newClock New clock to use.
-         */
-        @SdkTestInternalApi
-        public static void set(SdkClock newClock) {
-            clock = newClock;
-        }
-
-        /**
-         * Reset the clock to {@link #STANDARD}. Should only be used by SDK tests.
-         */
-        @SdkTestInternalApi
-        public static void reset() {
-            clock = STANDARD;
-        }
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/ServiceAwareSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ServiceAwareSigner.java
--- ./src/main/java/com/amazonaws/auth/ServiceAwareSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/ServiceAwareSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-/**
- * A signer that needs to know which service it is talking to.
- */
-public interface ServiceAwareSigner extends Signer {
-    /**
-     * Configure this signer with the name of the service it will be used
-     * to sign requests for.
-     *
-     * @param value   The name of the service.
-     */
-    void setServiceName(String value);
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SignatureVersion.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignatureVersion.java
--- ./src/main/java/com/amazonaws/auth/SignatureVersion.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignatureVersion.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-public enum SignatureVersion {
-
-    V1("1"), V2("2");
-
-    private String value;
-
-    private SignatureVersion(String value) {
-        this.value = value;
-    }
-
-    @Override
-    public String toString() {
-        return this.value;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SignerAsRequestSigner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerAsRequestSigner.java
--- ./src/main/java/com/amazonaws/auth/SignerAsRequestSigner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerAsRequestSigner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,48 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *   http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws.auth;
-
-import com.amazonaws.SignableRequest;
-
-/**
- * An adapter class that allows a {@link Signer} to implement the
- * {@link RequestSigner} interface
- */
-public final class SignerAsRequestSigner implements RequestSigner {
-    private final Signer signer;
-    private final AWSCredentialsProvider credentialsProvider;
-
-    /**
-     * Creates a {@link SignerAsRequestSigner}
-     * @param signer
-     *          the underlying {@link Signer} to use to actually sign the request
-     * @param credentialsProvider
-     *          the credentialsProvider to use to pass {@link AWSCredentials} to the underlying {@link Signer}
-     */
-    public SignerAsRequestSigner(Signer signer, AWSCredentialsProvider credentialsProvider) {
-        this.signer = signer;
-        this.credentialsProvider = credentialsProvider;
-    }
-
-    /**
-     * @see RequestSigner#sign(SignableRequest)
-     */
-    @Override
-    public void sign(SignableRequest<?> request) {
-        signer.sign(request, credentialsProvider.getCredentials());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SignerFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerFactory.java
--- ./src/main/java/com/amazonaws/auth/SignerFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,181 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.internal.config.InternalConfig;
-import com.amazonaws.internal.config.SignerConfig;
-
-/** Signer factory. */
-public final class SignerFactory {
-
-    public static final String QUERY_STRING_SIGNER = "QueryStringSignerType";
-    public static final String VERSION_THREE_SIGNER = "AWS3SignerType";
-    public static final String VERSION_FOUR_SIGNER = "AWS4SignerType";
-    public static final String VERSION_FOUR_UNSIGNED_PAYLOAD_SIGNER = "AWS4UnsignedPayloadSignerType";
-    public static final String NO_OP_SIGNER = "NoOpSignerType";
-
-    private static final Map<String, Class<? extends Signer>> SIGNERS
-        = new ConcurrentHashMap<String, Class<? extends Signer>>();
-
-    static {
-        // Register the standard signer types.
-        SIGNERS.put(QUERY_STRING_SIGNER, QueryStringSigner.class);
-        SIGNERS.put(VERSION_THREE_SIGNER, AWS3Signer.class);
-        SIGNERS.put(VERSION_FOUR_SIGNER, AWS4Signer.class);
-        SIGNERS.put(VERSION_FOUR_UNSIGNED_PAYLOAD_SIGNER, AWS4UnsignedPayloadSigner.class);
-        SIGNERS.put(NO_OP_SIGNER, NoOpSigner.class);
-    }
-
-    /**
-     * Private so you're not tempted to instantiate me.
-     */
-    private SignerFactory() {
-    }
-
-    /**
-     * Register an implementation class for the given signer type.
-     *
-     * @param signerType  The name of the signer type to register.
-     * @param signerClass The class implementing the given signature protocol.
-     */
-    public static void registerSigner(
-            final String signerType,
-            final Class<? extends Signer> signerClass) {
-
-        if (signerType == null) {
-            throw new IllegalArgumentException("signerType cannot be null");
-        }
-        if (signerClass == null) {
-            throw new IllegalArgumentException("signerClass cannot be null");
-        }
-
-        SIGNERS.put(signerType, signerClass);
-    }
-
-    /**
-     * Returns a non-null signer for the specified service and region according
-     * to the internal configuration which provides a basic default algorithm
-     * used for signer determination.
-     *
-     * @param serviceName
-     *            The name of the service to talk to.
-     * @param regionName
-     *            The name of the region to talk to; not necessarily the region
-     *            used for signing.
-     */
-    public static Signer getSigner(String serviceName, String regionName) {
-        return lookupAndCreateSigner(serviceName, regionName);
-    }
-
-    /**
-     * Returns an instance of the given signer type and configures it with the
-     * given service name (if applicable).
-     *
-     * @param signerType
-     *            The type of signer to create.
-     * @param serviceName
-     *            The name of the service to configure on the signer.
-     * @return a non-null signer.
-     */
-    public static Signer getSignerByTypeAndService(String signerType,
-            final String serviceName) {
-        return createSigner(signerType, serviceName);
-    }
-
-    private static String lookUpSignerTypeByServiceAndRegion(String serviceName, String regionName) {
-        InternalConfig config = InternalConfig.Factory.getInternalConfig();
-        SignerConfig signerConfig =
-                config.getSignerConfig(serviceName, regionName);
-        return signerConfig.getSignerType();
-    }
-
-    /**
-     * Internal implementation for looking up and creating a signer by service
-     * name and region.
-     */
-    private static Signer lookupAndCreateSigner(String serviceName, String regionName) {
-        String signerType = lookUpSignerTypeByServiceAndRegion(serviceName, regionName);
-        return createSigner(signerType, serviceName);
-    }
-
-    /**
-     * Internal implementation to create a signer by type and service name,
-     * and configuring it with the service name if applicable.
-     */
-    private static Signer createSigner(String signerType,
-            final String serviceName) {
-        Class<? extends Signer> signerClass = SIGNERS.get(signerType);
-        if (signerClass == null)
-            throw new IllegalArgumentException("unknown signer type: " + signerType);
-        Signer signer = createSigner(signerType);
-
-        if (signer instanceof ServiceAwareSigner) {
-            ((ServiceAwareSigner) signer).setServiceName(serviceName);
-        }
-        return signer;
-    }
-
-    /**
-     * Create an instance of the given signer type and initialize it with the
-     * given parameters.
-     *
-     * @param signerType The signer type.
-     * @param params The parameters to intialize the signer with.
-     *
-     * @return The new signer instance.
-     */
-    @SdkProtectedApi
-    public static Signer createSigner(String signerType, SignerParams params) {
-        Signer signer = createSigner(signerType);
-
-        if (signer instanceof ServiceAwareSigner) {
-            ((ServiceAwareSigner) signer).setServiceName(params.getServiceName());
-        }
-
-        if (signer instanceof RegionAwareSigner) {
-            ((RegionAwareSigner) signer).setRegionName(params.getRegionName());
-        }
-
-        return signer;
-    }
-
-    /**
-     * Create an instance of the given signer.
-     *
-     * @param signerType The signer type.
-     *
-     * @return The new signer instance.
-     */
-    private static Signer createSigner(String signerType) {
-        Class<? extends Signer> signerClass = SIGNERS.get(signerType);
-        Signer signer;
-        try {
-            signer = signerClass.newInstance();
-        } catch (InstantiationException ex) {
-            throw new IllegalStateException(
-                    "Cannot create an instance of " + signerClass.getName(),
-                    ex);
-        } catch (IllegalAccessException ex) {
-            throw new IllegalStateException(
-                    "Cannot create an instance of " + signerClass.getName(),
-                    ex);
-        }
-        return signer;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/Signer.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/Signer.java
--- ./src/main/java/com/amazonaws/auth/Signer.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/Signer.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,33 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.SignableRequest;
-
-/**
- * A strategy for applying cryptographic signatures to a request, proving
- * that the request was made by someone in posession of the given set of
- * credentials without transmitting the secret key over the wire.
- */
-public interface Signer {
-    /**
-     * Sign the given request with the given set of credentials. Modifies the
-     * passed-in request to apply the signature.
-     *
-     * @param request      The request to sign.
-     * @param credentials  The credentials to sign the request with.
-     */
-    public void sign(SignableRequest<?> request, AWSCredentials credentials);
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SignerParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerParams.java
--- ./src/main/java/com/amazonaws/auth/SignerParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-/**
- * Shared parameter structure to contain information required for signing by
- * various signer implementations.
- */
-public class SignerParams {
-    private String serviceName;
-    private String regionName;
-
-    public SignerParams(String serviceName, String regionName) {
-        this.serviceName = serviceName;
-        this.regionName = regionName;
-    }
-
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    public String getRegionName() {
-        return regionName;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SignerTypeAware.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerTypeAware.java
--- ./src/main/java/com/amazonaws/auth/SignerTypeAware.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SignerTypeAware.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,22 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-/**
- * Used to mark implementations of {@link com.amazonaws.AmazonWebServiceRequest} that specify a custom signer type.
- */
-public interface SignerTypeAware {
-    String getSignerType();
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/SigningAlgorithm.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SigningAlgorithm.java
--- ./src/main/java/com/amazonaws/auth/SigningAlgorithm.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/SigningAlgorithm.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,51 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.SdkClientException;
-
-import javax.crypto.Mac;
-import java.security.NoSuchAlgorithmException;
-
-public enum SigningAlgorithm {
-
-    HmacSHA1,
-    HmacSHA256;
-
-    private final ThreadLocal<Mac> macReference;
-
-    private SigningAlgorithm() {
-        final String algorithmName = this.toString();
-        macReference = new ThreadLocal<Mac>() {
-            @Override
-            protected Mac initialValue() {
-                try {
-                    return Mac.getInstance(algorithmName);
-                } catch (NoSuchAlgorithmException e) {
-                    throw new SdkClientException("Unable to fetch Mac instance for Algorithm "
-                            + algorithmName + e.getMessage(),e);
-
-                }
-            }
-        };
-    }
-
-    /**
-     * Returns the thread local reference for the crypto algorithm
-     */
-    public Mac getMac() {
-        return macReference.get();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/auth/StaticSignerProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/StaticSignerProvider.java
--- ./src/main/java/com/amazonaws/auth/StaticSignerProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/auth/StaticSignerProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.auth;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.internal.auth.SignerProvider;
-import com.amazonaws.internal.auth.SignerProviderContext;
-
-/**
- * Implementation of {@link SignerProvider} that always returns the same signer regardless of
- * context.
- */
-@SdkProtectedApi
-public class StaticSignerProvider extends SignerProvider {
-
-    private final Signer signer;
-
-    public StaticSignerProvider(Signer signer) {
-        this.signer = signer;
-    }
-
-    @Override
-    public Signer getSigner(SignerProviderContext context) {
-        return signer;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/AwsAsyncClientParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/AwsAsyncClientParams.java
--- ./src/main/java/com/amazonaws/client/AwsAsyncClientParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/AwsAsyncClientParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import java.util.concurrent.ExecutorService;
-
-/**
- * Provides access to all params needed in a asynchronous AWS service client constructor. Abstract
- * to allow additions to the params while maintaining backwards compatibility.
- */
-@SdkProtectedApi
-public abstract class AwsAsyncClientParams extends AwsSyncClientParams {
-
-    public abstract ExecutorService getExecutor();
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/AwsSyncClientParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/AwsSyncClientParams.java
--- ./src/main/java/com/amazonaws/client/AwsSyncClientParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/AwsSyncClientParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client;
-
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.handlers.RequestHandler2;
-import com.amazonaws.internal.auth.SignerProvider;
-import com.amazonaws.metrics.RequestMetricCollector;
-import com.amazonaws.retry.RetryPolicyAdapter;
-import com.amazonaws.retry.v2.RetryPolicy;
-
-import java.net.URI;
-import java.util.List;
-
-/**
- * Provides access to all params needed in a synchronous AWS service client constructor. Abstract
- * to allow additions to the params while maintaining backwards compatibility.
- */
-@SdkProtectedApi
-public abstract class AwsSyncClientParams {
-
-    public abstract AWSCredentialsProvider getCredentialsProvider();
-
-    public abstract ClientConfiguration getClientConfiguration();
-
-    public abstract RequestMetricCollector getRequestMetricCollector();
-
-    public abstract List<RequestHandler2> getRequestHandlers();
-
-    public SignerProvider getSignerProvider() {
-        // Not currently used by AWS clients. The builder uses setRegion to configure endpoint
-        // and signer and does not support custom endpoints or signers.
-        return null;
-    }
-
-    public URI getEndpoint() {
-        // Not currently used by AWS clients. The builder uses setRegion to configure endpoint
-        // and signer and does not support custom endpoints or signers.
-        return null;
-    }
-
-    public RetryPolicy getRetryPolicy() {
-        final ClientConfiguration config = getClientConfiguration();
-        return new RetryPolicyAdapter(config.getRetryPolicy(), config);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/builder/AwsAsyncClientBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/AwsAsyncClientBuilder.java
--- ./src/main/java/com/amazonaws/client/builder/AwsAsyncClientBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/AwsAsyncClientBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,118 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client.builder;
-
-import com.amazonaws.ClientConfigurationFactory;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.client.AwsAsyncClientParams;
-import com.amazonaws.regions.AwsRegionProvider;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Base class for all service specific async client builders.
- *
- * @param <Subclass> Concrete builder type, used for better fluent methods.
- */
-@NotThreadSafe
-@SdkProtectedApi
-public abstract class AwsAsyncClientBuilder<Subclass extends AwsAsyncClientBuilder, TypeToBuild> extends
-                                                                                                 AwsClientBuilder<Subclass, TypeToBuild> {
-    private ExecutorFactory executorFactory;
-
-    protected AwsAsyncClientBuilder(ClientConfigurationFactory clientConfigFactory) {
-        super(clientConfigFactory);
-    }
-
-    @SdkTestInternalApi
-    protected AwsAsyncClientBuilder(ClientConfigurationFactory clientConfigFactory,
-                                    AwsRegionProvider regionProvider) {
-        super(clientConfigFactory, regionProvider);
-    }
-
-
-    /**
-     * @return The {@link ExecutorFactory} currently configured by the client.
-     */
-    public final ExecutorFactory getExecutorFactory() {
-        return executorFactory;
-    }
-
-    /**
-     * Sets a custom executor service factory to use for the async clients. The factory will be
-     * called for each async client created through the builder.
-     *
-     * @param executorFactory Factory supplying new instances of {@link ExecutorService}
-     */
-    public final void setExecutorFactory(ExecutorFactory executorFactory) {
-        this.executorFactory = executorFactory;
-    }
-
-    /**
-     * Sets a custom executor service factory to use for the async clients. The factory will be
-     * called for each async client created through the builder.
-     *
-     * @param executorFactory Factory supplying new instances of {@link ExecutorService}
-     * @return This object for method chaining.
-     */
-    public final Subclass withExecutorFactory(ExecutorFactory executorFactory) {
-        setExecutorFactory(executorFactory);
-        return getSubclass();
-    }
-
-    @Override
-    public final TypeToBuild build() {
-        return configureMutableProperties(build(getAsyncClientParams()));
-    }
-
-    protected abstract TypeToBuild build(AwsAsyncClientParams asyncClientParams);
-
-    /**
-     * @return An instance of AwsAsyncClientParams that has all params to be used in the async
-     * client constructor.
-     */
-    protected final AwsAsyncClientParams getAsyncClientParams() {
-        return new AsyncBuilderParams(executorFactory);
-    }
-
-    /**
-     * Presents a view of the builder to be used in the async client constructor.
-     */
-    protected class AsyncBuilderParams extends SyncBuilderParams {
-
-        private final ExecutorService _executorService;
-
-        protected AsyncBuilderParams(ExecutorFactory executorFactory) {
-            this._executorService =
-                    (executorFactory == null) ? defaultExecutor() : executorFactory.newExecutor();
-        }
-
-        @Override
-        public ExecutorService getExecutor() {
-            return this._executorService;
-        }
-
-        /**
-         * @return Default async Executor to use if none is explicitly provided by user.
-         */
-        private ExecutorService defaultExecutor() {
-            return Executors.newFixedThreadPool(getClientConfiguration().getMaxConnections());
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/builder/AwsClientBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/AwsClientBuilder.java
--- ./src/main/java/com/amazonaws/client/builder/AwsClientBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/AwsClientBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,469 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client.builder;
-
-import com.amazonaws.AmazonWebServiceClient;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.ClientConfigurationFactory;
-import com.amazonaws.PredefinedClientConfigurations;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
-import com.amazonaws.client.AwsAsyncClientParams;
-import com.amazonaws.client.AwsSyncClientParams;
-import com.amazonaws.handlers.RequestHandler2;
-import com.amazonaws.metrics.RequestMetricCollector;
-import com.amazonaws.regions.AwsRegionProvider;
-import com.amazonaws.regions.DefaultAwsRegionProviderChain;
-import com.amazonaws.regions.Region;
-import com.amazonaws.regions.RegionUtils;
-import com.amazonaws.regions.Regions;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-
-/**
- * Base class for all service specific client builders.
- *
- * @param <Subclass> Concrete builder type, used for better fluent methods.
- * @param <TypeToBuild>  Type that this builder builds.
- */
-@NotThreadSafe
-@SdkProtectedApi
-public abstract class AwsClientBuilder<Subclass extends AwsClientBuilder, TypeToBuild> {
-
-    /**
-     * Default Region Provider chain. Used only when the builder is not explicitly configured with a
-     * region.
-     */
-    private static final AwsRegionProvider DEFAULT_REGION_PROVIDER = new DefaultAwsRegionProviderChain();
-
-    /**
-     * Different services may have custom client configuration factories to vend defaults tailored
-     * for that service. If no explicit client configuration is provided to the builder the default
-     * factory for the service is used.
-     */
-    private final ClientConfigurationFactory clientConfigFactory;
-
-    /**
-     * {@link AwsRegionProvider} to use when no explicit region or endpointConfiguration is configured.
-     * This is currently not exposed for customization by customers.
-     */
-    private final AwsRegionProvider regionProvider;
-
-    private AWSCredentialsProvider credentials;
-    private ClientConfiguration clientConfig;
-    private RequestMetricCollector metricsCollector;
-    private Region region;
-    private List<RequestHandler2> requestHandlers;
-    private EndpointConfiguration endpointConfiguration;
-
-    protected AwsClientBuilder(ClientConfigurationFactory clientConfigFactory) {
-        this(clientConfigFactory, DEFAULT_REGION_PROVIDER);
-    }
-
-    @SdkTestInternalApi
-    protected AwsClientBuilder(ClientConfigurationFactory clientConfigFactory,
-                               AwsRegionProvider regionProvider) {
-        this.clientConfigFactory = clientConfigFactory;
-        this.regionProvider = regionProvider;
-    }
-
-    /**
-     * Gets the AWSCredentialsProvider currently configured in the builder.
-     */
-    public final AWSCredentialsProvider getCredentials() {
-        return this.credentials;
-    }
-
-    /**
-     * Sets the AWSCredentialsProvider used by the client. If not specified the default is {@link
-     * DefaultAWSCredentialsProviderChain}.
-     *
-     * @param credentialsProvider New AWSCredentialsProvider to use.
-     */
-    public final void setCredentials(AWSCredentialsProvider credentialsProvider) {
-        this.credentials = credentialsProvider;
-    }
-
-    /**
-     * Sets the AWSCredentialsProvider used by the client. If not specified the default is {@link
-     * DefaultAWSCredentialsProviderChain}.
-     *
-     * @param credentialsProvider New AWSCredentialsProvider to use.
-     * @return This object for method chaining.
-     */
-    public final Subclass withCredentials(AWSCredentialsProvider credentialsProvider) {
-        setCredentials(credentialsProvider);
-        return getSubclass();
-    }
-
-    /**
-     * If the builder isn't explicitly configured with credentials we use the {@link
-     * DefaultAWSCredentialsProviderChain}.
-     */
-    private AWSCredentialsProvider resolveCredentials() {
-        return (credentials == null) ? DefaultAWSCredentialsProviderChain.getInstance() : credentials;
-    }
-
-    /**
-     * Gets the ClientConfiguration currently configured in the builder
-     */
-    public final ClientConfiguration getClientConfiguration() {
-        return this.clientConfig;
-    }
-
-    /**
-     * Sets the ClientConfiguration to be used by the client. If not specified the default is
-     * typically {@link PredefinedClientConfigurations#defaultConfig} but may differ per service.
-     *
-     * @param config Custom configuration to use
-     */
-    public final void setClientConfiguration(ClientConfiguration config) {
-        this.clientConfig = config;
-    }
-
-    /**
-     * Sets the ClientConfiguration to be used by the client. If not specified the default is
-     * typically {@link PredefinedClientConfigurations#defaultConfig} but may differ per service.
-     *
-     * @param config Custom configuration to use
-     * @return This object for method chaining.
-     */
-    public final Subclass withClientConfiguration(ClientConfiguration config) {
-        setClientConfiguration(config);
-        return getSubclass();
-    }
-
-    /**
-     * If not explicit client configuration is provided we consult the {@link
-     * ClientConfigurationFactory} of the service. If an explicit configuration is provided we use
-     * ClientConfiguration's copy constructor to avoid mutation.
-     */
-    private ClientConfiguration resolveClientConfiguration() {
-        return (clientConfig == null) ? clientConfigFactory.getConfig() :
-                new ClientConfiguration(clientConfig);
-    }
-
-    /**
-     * Gets the {@link RequestMetricCollector} in use by the builder.
-     */
-    public final RequestMetricCollector getMetricsCollector() {
-        return this.metricsCollector;
-    }
-
-    /**
-     * Sets a custom RequestMetricCollector to use for the client.
-     *
-     * @param metrics Custom RequestMetricCollector to use.
-     */
-    public final void setMetricsCollector(RequestMetricCollector metrics) {
-        this.metricsCollector = metrics;
-    }
-
-    /**
-     * Sets a custom RequestMetricCollector to use for the client.
-     *
-     * @param metrics Custom RequestMetricCollector to use.
-     * @return This object for method chaining.
-     */
-    public final Subclass withMetricsCollector(RequestMetricCollector metrics) {
-        setMetricsCollector(metrics);
-        return getSubclass();
-    }
-
-    /**
-     * Gets the region in use by the builder.
-     */
-    public final String getRegion() {
-        return region == null ? null : region.getName();
-    }
-
-    /**
-     * Sets the region to be used by the client. This will be used to determine both the
-     * service endpoint (eg: https://sns.us-west-1.amazonaws.com) and signing region (eg: us-west-1)
-     * for requests. If neither region or endpoint configuration {@link #setEndpointConfiguration(EndpointConfiguration)}
-     * are explicitly provided in the builder the {@link #DEFAULT_REGION_PROVIDER} is consulted.
-     *
-     * @param region Region to use
-     */
-    public final void setRegion(String region) {
-        withRegion(region);
-    }
-
-    /**
-     * Sets the region to be used by the client. This will be used to determine both the
-     * service endpoint (eg: https://sns.us-west-1.amazonaws.com) and signing region (eg: us-west-1)
-     * for requests. If neither region or endpoint configuration {@link #setEndpointConfiguration(EndpointConfiguration)}
-     * are explicitly provided in the builder the {@link #DEFAULT_REGION_PROVIDER} is consulted.
-     *
-     * <p> For regions not explicitly in the {@link Regions} enum use the {@link
-     * #withRegion(String)} overload.</p>
-     *
-     * @param region Region to use
-     * @return This object for method chaining.
-     */
-    public final Subclass withRegion(Regions region) {
-        return withRegion(region.getName());
-    }
-
-    /**
-     * Sets the region to be used by the client. This will be used to determine both the
-     * service endpoint (eg: https://sns.us-west-1.amazonaws.com) and signing region (eg: us-west-1)
-     * for requests. If neither region or endpoint configuration {@link #setEndpointConfiguration(EndpointConfiguration)}
-     * are explicitly provided in the builder the {@link #DEFAULT_REGION_PROVIDER} is consulted.
-     *
-     * @param region Region to use
-     * @return This object for method chaining.
-     */
-    public final Subclass withRegion(String region) {
-        return withRegion(RegionUtils.getRegion(region));
-    }
-
-    /**
-     * Sets the region to be used by the client. This will be used to determine both the
-     * service endpoint (eg: https://sns.us-west-1.amazonaws.com) and signing region (eg: us-west-1)
-     * for requests. If neither region or endpoint configuration {@link #setEndpointConfiguration(EndpointConfiguration)}
-     * are explicitly provided in the builder the {@link #DEFAULT_REGION_PROVIDER} is consulted.
-     *
-     * @param region Region to use, this will be used to determine both service endpoint
-     *               and the signing region
-     * @return This object for method chaining.
-     */
-    private Subclass withRegion(Region region) {
-        this.region = region;
-        return getSubclass();
-    }
-
-    /**
-     * Gets the service endpointConfiguration in use by the builder
-     */
-    public final EndpointConfiguration getEndpoint() {
-        return endpointConfiguration;
-    }
-
-    /**
-     * Sets the endpoint configuration (service endpoint & signing region) to be used for requests. If neither region {@link #setRegion(String)}
-     * or endpoint configuration are explicitly provided in the builder the {@link #DEFAULT_REGION_PROVIDER} is consulted.
-     *
-     * <p><b>Only use this if using a non-standard service endpoint - the recommended approach for configuring a client is to use {@link #setRegion(String)}</b>
-     *
-     * @param endpointConfiguration The endpointConfiguration to use
-     */
-    public final void setEndpointConfiguration(EndpointConfiguration endpointConfiguration) {
-        withEndpointConfiguration(endpointConfiguration);
-    }
-
-    /**
-     * Sets the endpoint configuration (service endpoint & signing region) to be used for requests. If neither region {@link #withRegion(String)}
-     * or endpoint configuration are explicitly provided in the builder the {@link #DEFAULT_REGION_PROVIDER} is consulted.
-     *
-     * <p><b>Only use this if using a non-standard service endpoint - the recommended approach for configuring a client is to use {@link #withRegion(String)}</b>
-     *
-     * @param endpointConfiguration The endpointConfiguration to use
-     * @return This object for method chaining.
-     */
-    public final Subclass withEndpointConfiguration(EndpointConfiguration endpointConfiguration) {
-        this.endpointConfiguration = endpointConfiguration;
-        return getSubclass();
-    }
-
-    /**
-     * Gets the list of request handlers in use by the builder.
-     */
-    public final List<RequestHandler2> getRequestHandlers() {
-        return this.requestHandlers == null ? null :
-                Collections.unmodifiableList(this.requestHandlers);
-    }
-
-    /**
-     * Sets the request handlers to use in the client.
-     *
-     * @param handlers Request handlers to use for client.
-     */
-    public final void setRequestHandlers(RequestHandler2... handlers) {
-        this.requestHandlers = Arrays.asList(handlers);
-    }
-
-    /**
-     * Sets the request handlers to use in the client.
-     *
-     * @param handlers Request handlers to use for client.
-     * @return This object for method chaining.
-     */
-    public final Subclass withRequestHandlers(RequestHandler2... handlers) {
-        setRequestHandlers(handlers);
-        return getSubclass();
-    }
-
-    /**
-     * Request handlers are copied to a new list to avoid mutation, if no request handlers are
-     * provided to the builder we supply an empty list.
-     */
-    private List<RequestHandler2> resolveRequestHandlers() {
-        return (requestHandlers == null) ? new ArrayList<RequestHandler2>() :
-                new ArrayList<RequestHandler2>(requestHandlers);
-    }
-
-    /**
-     * Region and endpoint logic is tightly coupled to the client class right now so it's easier to
-     * set them after client creation and let the normal logic kick in. Ideally this should resolve
-     * the endpoint and signer information here and just pass that information as is to the client.
-     *
-     * @param clientInterface Client to configure
-     */
-    @SdkInternalApi
-    final TypeToBuild configureMutableProperties(TypeToBuild clientInterface) {
-        AmazonWebServiceClient client = (AmazonWebServiceClient) clientInterface;
-        setRegion(client);
-        client.makeImmutable();
-        return clientInterface;
-    }
-
-    /**
-     * Builds a client with the configure properties.
-     *
-     * @return Client instance to make API calls with.
-     */
-    public abstract TypeToBuild build();
-
-    /**
-     * @return An instance of AwsSyncClientParams that has all params to be used in the sync client
-     * constructor.
-     */
-    protected final AwsSyncClientParams getSyncClientParams() {
-        return new SyncBuilderParams();
-    }
-
-    private void setRegion(AmazonWebServiceClient client) {
-        if (region != null && endpointConfiguration != null) {
-            throw new IllegalStateException("Only one of Region or EndpointConfiguration may be set.");
-        }
-        if (endpointConfiguration != null) {
-            client.setEndpoint(endpointConfiguration.getServiceEndpoint());
-            client.setSignerRegionOverride(endpointConfiguration.getSigningRegion());
-        } else if (region != null) {
-            client.setRegion(region);
-        } else {
-            final String region = determineRegionFromRegionProvider();
-            if (region != null) {
-                client.setRegion(RegionUtils.getRegion(region));
-            } else {
-                throw new SdkClientException(
-                        "Unable to find a region via the region provider chain. " +
-                        "Must provide an explicit region in the builder or setup environment to supply a region.");
-            }
-        }
-    }
-
-    /**
-     * Attempt to determine the region from the configured region provider. This will return null in the event that the
-     * region provider could not determine the region automatically.
-     */
-    private String determineRegionFromRegionProvider() {
-        try {
-            return regionProvider.getRegion();
-        }
-        catch (SdkClientException e) {
-            // The AwsRegionProviderChain that is used by default throws an exception instead of returning null when
-            // the region is not defined. For that reason, we have to support both throwing an exception and returning
-            // null as the region not being defined.
-            return null;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected final Subclass getSubclass() {
-        return (Subclass) this;
-    }
-
-    /**
-     * Presents a view of the builder to be used in a client constructor.
-     */
-    protected class SyncBuilderParams extends AwsAsyncClientParams {
-
-
-        private final ClientConfiguration _clientConfig;
-        private final AWSCredentialsProvider _credentials;
-        private final RequestMetricCollector _metricsCollector;
-        private final List<RequestHandler2> _requestHandlers;
-
-        protected SyncBuilderParams() {
-            this._clientConfig = resolveClientConfiguration();
-            this._credentials = resolveCredentials();
-            this._metricsCollector = metricsCollector;
-            this._requestHandlers = resolveRequestHandlers();
-        }
-
-        @Override
-        public AWSCredentialsProvider getCredentialsProvider() {
-            return this._credentials;
-        }
-
-        @Override
-        public ClientConfiguration getClientConfiguration() {
-            return this._clientConfig;
-        }
-
-        @Override
-        public RequestMetricCollector getRequestMetricCollector() {
-            return this._metricsCollector;
-        }
-
-        @Override
-        public List<RequestHandler2> getRequestHandlers() {
-            return this._requestHandlers;
-        }
-
-        @Override
-        public ExecutorService getExecutor() {
-            throw new UnsupportedOperationException("ExecutorService is not used for sync client.");
-        }
-
-    }
-
-    /**
-     * A container for configuration required to submit requests to a service (service endpoint and signing region)
-     */
-    public static final class EndpointConfiguration {
-        private final String serviceEndpoint;
-        private final String signingRegion;
-
-        /**
-         * @param serviceEndpoint the service endpoint either with or without the protocol (e.g. https://sns.us-west-1.amazonaws.com or sns.us-west-1.amazonaws.com)
-         * @param signingRegion the region to use for SigV4 signing of requests (e.g. us-west-1)
-         */
-        public EndpointConfiguration(String serviceEndpoint, String signingRegion) {
-            this.serviceEndpoint = serviceEndpoint;
-            this.signingRegion = signingRegion;
-        }
-
-        public String getServiceEndpoint() {
-            return serviceEndpoint;
-        }
-
-        public String getSigningRegion() {
-            return signingRegion;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/builder/AwsSyncClientBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/AwsSyncClientBuilder.java
--- ./src/main/java/com/amazonaws/client/builder/AwsSyncClientBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/AwsSyncClientBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,57 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client.builder;
-
-import com.amazonaws.ClientConfigurationFactory;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.client.AwsSyncClientParams;
-import com.amazonaws.regions.AwsRegionProvider;
-
-/**
- * Base class for all service specific sync client builders.
- *
- * @param <Subclass>    Concrete builder type, used for better fluent methods.
- * @param <TypeToBuild> Client interface this builder can build.
- */
-@NotThreadSafe
-@SdkProtectedApi
-public abstract class AwsSyncClientBuilder<Subclass extends AwsSyncClientBuilder, TypeToBuild> extends
-                                                                                               AwsClientBuilder<Subclass, TypeToBuild> {
-    protected AwsSyncClientBuilder(ClientConfigurationFactory clientConfigFactory) {
-        super(clientConfigFactory);
-    }
-
-    @SdkTestInternalApi
-    protected AwsSyncClientBuilder(ClientConfigurationFactory clientConfigFactory,
-                                   AwsRegionProvider regionProvider) {
-        super(clientConfigFactory, regionProvider);
-    }
-
-    @Override
-    public final TypeToBuild build() {
-        return configureMutableProperties(build(getSyncClientParams()));
-    }
-
-    /**
-     * Overriden by subclasses to call the client constructor.
-     *
-     * @param clientParams Client Params to create client with
-     * @return Built client.
-     */
-    protected abstract TypeToBuild build(AwsSyncClientParams clientParams);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/builder/ExecutorFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/ExecutorFactory.java
--- ./src/main/java/com/amazonaws/client/builder/ExecutorFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/builder/ExecutorFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client.builder;
-
-import java.util.concurrent.ExecutorService;
-
-/**
- * Factory to create instances of {@link ExecutorService}.
- */
-public interface ExecutorFactory {
-
-    /**
-     * @return New {@link ExecutorService}
-     */
-    ExecutorService newExecutor();
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/ClientExecutionParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientExecutionParams.java
--- ./src/main/java/com/amazonaws/client/ClientExecutionParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientExecutionParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,89 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.Request;
-import com.amazonaws.RequestConfig;
-import com.amazonaws.SdkBaseException;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.http.HttpResponseHandler;
-import com.amazonaws.transform.Marshaller;
-
-/**
- * Encapsulates parameters needed for a particular API call. Captures input and output pojo types.
- *
- * @param <Input>  Input POJO type.
- * @param <Output> Output POJO type.
- */
-@SdkProtectedApi
-@NotThreadSafe
-public class ClientExecutionParams<Input, Output> {
-
-    private Input input;
-    private Marshaller<Request<Input>, Input> marshaller;
-    private HttpResponseHandler<Output> responseHandler;
-    private HttpResponseHandler<? extends SdkBaseException> errorResponseHandler;
-    private RequestConfig requestConfig;
-
-    public Marshaller<Request<Input>, Input> getMarshaller() {
-        return marshaller;
-    }
-
-    public ClientExecutionParams<Input, Output> withMarshaller(
-            Marshaller<Request<Input>, Input> marshaller) {
-        this.marshaller = marshaller;
-        return this;
-    }
-
-    public Input getInput() {
-        return input;
-    }
-
-    public ClientExecutionParams<Input, Output> withInput(Input input) {
-        this.input = input;
-        return this;
-    }
-
-    public HttpResponseHandler<Output> getResponseHandler() {
-        return responseHandler;
-    }
-
-    public ClientExecutionParams<Input, Output> withResponseHandler(
-            HttpResponseHandler<Output> responseHandler) {
-        this.responseHandler = responseHandler;
-        return this;
-    }
-
-    public HttpResponseHandler<? extends SdkBaseException> getErrorResponseHandler() {
-        return errorResponseHandler;
-    }
-
-    public ClientExecutionParams<Input, Output> withErrorResponseHandler(
-            HttpResponseHandler<? extends SdkBaseException> errorResponseHandler) {
-        this.errorResponseHandler = errorResponseHandler;
-        return this;
-    }
-
-    public RequestConfig getRequestConfig() {
-        return requestConfig;
-    }
-
-    public ClientExecutionParams<Input, Output> withRequestConfig(RequestConfig requestConfig) {
-        this.requestConfig = requestConfig;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/ClientHandlerImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientHandlerImpl.java
--- ./src/main/java/com/amazonaws/client/ClientHandlerImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientHandlerImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,238 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.RequestConfig;
-import com.amazonaws.Response;
-import com.amazonaws.SdkBaseException;
-import com.amazonaws.annotation.Immutable;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.handlers.RequestHandler2;
-import com.amazonaws.http.AmazonHttpClient;
-import com.amazonaws.http.ExecutionContext;
-import com.amazonaws.http.HttpResponseHandler;
-import com.amazonaws.internal.auth.SignerProvider;
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.metrics.RequestMetricCollector;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.CredentialUtils;
-
-import java.net.URI;
-import java.util.List;
-
-/**
- * Default implementation of {@link ClientHandler}.
- */
-@Immutable
-@ThreadSafe
-@SdkProtectedApi
-public class ClientHandlerImpl extends ClientHandler {
-
-    private final AWSCredentialsProvider awsCredentialsProvider;
-    private final SignerProvider signerProvider;
-    private final URI endpoint;
-    private final List<RequestHandler2> requestHandler2s;
-    private final RequestMetricCollector clientLevelMetricCollector;
-    private final AmazonHttpClient client;
-
-    public ClientHandlerImpl(ClientHandlerParams handlerParams) {
-        this.signerProvider = handlerParams.getClientParams().getSignerProvider();
-        this.endpoint = handlerParams.getClientParams().getEndpoint();
-        this.awsCredentialsProvider = handlerParams.getClientParams().getCredentialsProvider();
-        this.requestHandler2s = handlerParams.getClientParams().getRequestHandlers();
-        this.clientLevelMetricCollector = handlerParams.getClientParams().getRequestMetricCollector();
-        this.client = buildHttpClient(handlerParams);
-    }
-
-    private AmazonHttpClient buildHttpClient(ClientHandlerParams handlerParams) {
-        final AwsSyncClientParams clientParams = handlerParams.getClientParams();
-        return AmazonHttpClient.builder()
-                .clientConfiguration(clientParams.getClientConfiguration())
-                .retryPolicy(clientParams.getRetryPolicy())
-                .requestMetricCollector(clientParams.getRequestMetricCollector())
-                .useBrowserCompatibleHostNameVerifier(handlerParams.isDisableStrictHostnameVerification())
-                .build();
-    }
-
-    @Override
-    public <Input, Output> Output execute(
-            ClientExecutionParams<Input, Output> executionParams) {
-        final Input input = executionParams.getInput();
-        ExecutionContext executionContext = createExecutionContext(
-                executionParams.getRequestConfig());
-        AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics();
-        awsRequestMetrics.startEvent(AWSRequestMetrics.Field.ClientExecuteTime);
-        Request<Input> request = null;
-        Response<Output> response = null;
-
-        try {
-            awsRequestMetrics.startEvent(AWSRequestMetrics.Field.RequestMarshallTime);
-            try {
-                request = executionParams.getMarshaller().marshall(input);
-                request.setAWSRequestMetrics(awsRequestMetrics);
-            } finally {
-                awsRequestMetrics.endEvent(AWSRequestMetrics.Field.RequestMarshallTime);
-            }
-
-            response = invoke(request,
-                              executionParams.getRequestConfig(),
-                              executionContext,
-                              executionParams.getResponseHandler(),
-                              executionParams.getErrorResponseHandler());
-
-            return response.getAwsResponse();
-
-        } finally {
-
-            endClientExecution(awsRequestMetrics,
-                               executionParams.getRequestConfig(),
-                               request,
-                               response);
-        }
-    }
-
-    @Override
-    public void shutdown() {
-        client.shutdown();
-    }
-
-    private ExecutionContext createExecutionContext(RequestConfig requestConfig) {
-        boolean isMetricsEnabled = isRequestMetricsEnabled(requestConfig);
-        return ExecutionContext.builder()
-                .withRequestHandler2s(requestHandler2s)
-                .withUseRequestMetrics(isMetricsEnabled)
-                .withSignerProvider(signerProvider)
-                .build();
-    }
-
-    /**
-     * Returns true if request metric collection is applicable to the given request; false
-     * otherwise.
-     */
-    private boolean isRequestMetricsEnabled(RequestConfig requestConfig) {
-        return hasRequestMetricsCollector(requestConfig) || isRMCEnabledAtClientOrSdkLevel();
-    }
-
-    private boolean hasRequestMetricsCollector(RequestConfig requestConfig) {
-        return requestConfig.getRequestMetricsCollector() != null &&
-               requestConfig.getRequestMetricsCollector().isEnabled();
-    }
-
-    /**
-     * Returns true if request metric collection is enabled at the service client or AWS SDK level
-     * request; false otherwise.
-     */
-    private boolean isRMCEnabledAtClientOrSdkLevel() {
-        RequestMetricCollector collector = requestMetricCollector();
-        return collector != null && collector.isEnabled();
-    }
-
-    /**
-     * Returns the client specific request metric collector if there is one; or the one at the AWS
-     * SDK level otherwise.
-     */
-    private RequestMetricCollector requestMetricCollector() {
-        return clientLevelMetricCollector != null ? clientLevelMetricCollector :
-                AwsSdkMetrics.getRequestMetricCollector();
-    }
-
-
-    /**
-     * Runs the {@code beforeMarshalling} method of any {@code RequestHandler2}s associated with
-     * this client.
-     *
-     * @param request the request passed in from the user
-     * @return The (possibly different) request to marshall
-     */
-    @SuppressWarnings("unchecked")
-    protected final <T extends AmazonWebServiceRequest> T beforeMarshalling(T request) {
-        T local = request;
-        for (RequestHandler2 handler : requestHandler2s) {
-            local = (T) handler.beforeMarshalling(local);
-        }
-        return local;
-    }
-
-    /**
-     * Normal invoke with authentication. Credentials are required and may be overriden at the
-     * request level.
-     **/
-    private <Output, Input> Response<Output> invoke(Request<Input> request,
-                                                    RequestConfig requestConfig,
-                                                    ExecutionContext executionContext,
-                                                    HttpResponseHandler<Output> responseHandler,
-                                                    HttpResponseHandler<? extends SdkBaseException> errorResponseHandler) {
-
-        executionContext.setCredentialsProvider(CredentialUtils.getCredentialsProvider(
-                requestConfig, awsCredentialsProvider));
-
-        return doInvoke(request, requestConfig, executionContext, responseHandler,
-                        errorResponseHandler);
-    }
-
-    /**
-     * Invoke the request using the http client. Assumes credentials (or lack thereof) have been
-     * configured in the ExecutionContext beforehand.
-     **/
-    private <Output, Input> Response<Output> doInvoke(Request<Input> request,
-                                                      RequestConfig requestConfig,
-                                                      ExecutionContext executionContext,
-                                                      HttpResponseHandler<Output> responseHandler,
-                                                      HttpResponseHandler<? extends SdkBaseException> errorResponseHandler) {
-        request.setEndpoint(endpoint);
-        return client.requestExecutionBuilder()
-                .request(request)
-                .requestConfig(requestConfig)
-                .executionContext(executionContext)
-                .errorResponseHandler(errorResponseHandler)
-                .execute(responseHandler);
-    }
-
-    /**
-     * Convenient method to end the client execution without logging the awsRequestMetrics.
-     */
-    private void endClientExecution(AWSRequestMetrics awsRequestMetrics,
-                                          RequestConfig requestConfig,
-                                          Request<?> request,
-                                          Response<?> response) {
-        if (request != null) {
-            awsRequestMetrics.endEvent(AWSRequestMetrics.Field.ClientExecuteTime);
-            awsRequestMetrics.getTimingInfo().endTiming();
-            RequestMetricCollector metricCollector = findRequestMetricCollector(requestConfig);
-            metricCollector.collectMetrics(request, response);
-            awsRequestMetrics.log();
-        }
-    }
-
-    /**
-     * Returns the most specific request metric collector, starting from the request level, then
-     * client level, then finally the AWS SDK level.
-     */
-    private RequestMetricCollector findRequestMetricCollector(RequestConfig requestConfig) {
-        RequestMetricCollector reqLevelMetricsCollector = requestConfig
-                .getRequestMetricsCollector();
-        if (reqLevelMetricsCollector != null) {
-            return reqLevelMetricsCollector;
-        } else if (clientLevelMetricCollector != null) {
-            return clientLevelMetricCollector;
-        } else {
-            return AwsSdkMetrics.getRequestMetricCollector();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/ClientHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientHandler.java
--- ./src/main/java/com/amazonaws/client/ClientHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Client interface to invoke an API.
- */
-@SdkProtectedApi
-public abstract class ClientHandler {
-
-    /**
-     * Execute's a web service request. Handles marshalling and unmarshalling of data and making the
-     * underlying HTTP call(s).
-     *
-     * @param executionParams Parameters specific to this invocation of an API.
-     * @param <Input>         Input POJO type
-     * @param <Output>        Output POJO type
-     * @return Unmarshalled output POJO type.
-     */
-    public abstract <Input, Output> Output execute(
-            ClientExecutionParams<Input, Output> executionParams);
-
-    /**
-     * Shutdown and release any underlying resources.
-     */
-    public abstract void shutdown();
-}
diff -Nau8r ./src/main/java/com/amazonaws/client/ClientHandlerParams.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientHandlerParams.java
--- ./src/main/java/com/amazonaws/client/ClientHandlerParams.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/client/ClientHandlerParams.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.client;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Client level parameters for the {@link ClientHandler} implementation.
- */
-@SdkProtectedApi
-@NotThreadSafe
-public class ClientHandlerParams {
-
-    private AwsSyncClientParams clientParams;
-
-    /**
-     * By default we use strict hostname verification for SSL. S3 disables this due to wildcard
-     * certificates.
-     */
-    private boolean disableStrictHostnameVerification = false;
-
-    public AwsSyncClientParams getClientParams() {
-        return clientParams;
-    }
-
-    public ClientHandlerParams withClientParams(AwsSyncClientParams clientParams) {
-        this.clientParams = clientParams;
-        return this;
-    }
-
-    public boolean isDisableStrictHostnameVerification() {
-        return disableStrictHostnameVerification;
-    }
-
-
-    public ClientHandlerParams withDisableStrictHostnameVerification(
-            boolean disableStrictHostnameVerification) {
-        this.disableStrictHostnameVerification = disableStrictHostnameVerification;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/ClientConfigurationFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ClientConfigurationFactory.java
--- ./src/main/java/com/amazonaws/ClientConfigurationFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ClientConfigurationFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,61 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Factory producing predefined {@link ClientConfiguration} instances.
- * Individual service clients may extend this factory to override
- * these with service specific configuration values.
- */
-@SdkProtectedApi
-public class ClientConfigurationFactory {
-
-    /**
-     * Builds a {@link ClientConfiguration} instance with the default configuration
-     * for the current client.  If the {@link SDKGlobalConfiguration#ENABLE_IN_REGION_OPTIMIZED_MODE}
-     * system property has been set, in-region optimized configuration will be used.
-     *
-     * @return constructed {@link ClientConfiguration} instance
-     */
-    public final ClientConfiguration getConfig() {
-        return SDKGlobalConfiguration.isInRegionOptimizedModeEnabled()
-                ? getInRegionOptimizedConfig() : getDefaultConfig();
-    }
-
-    /**
-     * Builds a {@link ClientConfiguration} instance with default configuration
-     * values suitable for most use cases.
-     *
-     * @return constructed {@link ClientConfiguration} with standard configuration.
-     */
-    protected ClientConfiguration getDefaultConfig() {
-        return new ClientConfiguration();
-    }
-
-    /**
-     * Builds a {@link ClientConfiguration} instance with configuration values
-     * tailored towards clients operating in the same AWS region as the service
-     * endpoint they call.  Timeouts in in-region optimized configurations are
-     * generally set much lower than the client standard configuration.
-     *
-     * @return constructed {@link ClientConfiguration} with in-region optimized configuration
-     */
-    protected ClientConfiguration getInRegionOptimizedConfig() {
-        return new ClientConfiguration().withConnectionTimeout(1000);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/ClientConfiguration.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ClientConfiguration.java
--- ./src/main/java/com/amazonaws/ClientConfiguration.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ClientConfiguration.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,2114 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.http.IdleConnectionReaper;
-import com.amazonaws.retry.PredefinedRetryPolicies;
-import com.amazonaws.retry.RetryPolicy;
-import com.amazonaws.util.ValidationUtils;
-import com.amazonaws.util.VersionInfoUtils;
-import java.net.InetAddress;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Client configuration options such as proxy settings, user agent string, max retry attempts, etc.
- *
- * @see PredefinedClientConfigurations
- */
-@NotThreadSafe
-public class ClientConfiguration {
-
-    /** The default timeout for creating new connections. */
-    public static final int DEFAULT_CONNECTION_TIMEOUT = 10 * 1000;
-
-    /** The default timeout for reading from a connected socket. */
-    public static final int DEFAULT_SOCKET_TIMEOUT = 50 * 1000;
-
-    /**
-     * The default timeout for a request. This is disabled by default.
-     */
-    public static final int DEFAULT_REQUEST_TIMEOUT = 0;
-
-    /**
-     * The default timeout for a request. This is disabled by default.
-     */
-    public static final int DEFAULT_CLIENT_EXECUTION_TIMEOUT = 0;
-
-    /** The default max connection pool size. */
-    public static final int DEFAULT_MAX_CONNECTIONS = 50;
-
-    /**
-     * The default on whether to utilize the USE_EXPECT_CONTINUE handshake for operations. Currently
-     * only honored for PUT operations.
-     */
-    public static final boolean DEFAULT_USE_EXPECT_CONTINUE = true;
-
-    /** The default HTTP user agent header for AWS Java SDK clients. */
-    public static final String DEFAULT_USER_AGENT = VersionInfoUtils.getUserAgent();
-
-    /**
-     * Default request retry policy, including the maximum retry count of 3, the default retry
-     * condition and the default back-off strategy.
-     *
-     * @see PredefinedRetryPolicies#DEFAULT
-     * @see PredefinedRetryPolicies#DYNAMODB_DEFAULT
-     */
-    public static final RetryPolicy DEFAULT_RETRY_POLICY = PredefinedRetryPolicies.DEFAULT;
-
-    /**
-     * The default on whether to use the {@link IdleConnectionReaper} to manage stale connections
-     *
-     * @see IdleConnectionReaper
-     */
-    public static final boolean DEFAULT_USE_REAPER = true;
-
-    /**
-     * The default on whether to use gzip compression.
-     */
-    public static final boolean DEFAULT_USE_GZIP = false;
-
-    /**
-     * The default expiration time (in milliseconds) for a connection in the connection pool.
-     */
-    public static final long DEFAULT_CONNECTION_TTL = -1;
-
-    /**
-     * The default maximum idle time (in milliseconds) for a connection in the connection pool.
-     */
-    public static final long DEFAULT_CONNECTION_MAX_IDLE_MILLIS = 60 * 1000;
-
-    /**
-     * The default time a connection can be idle in the connection pool before it must be validated that it's still open.
-     */
-    public static final int DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS = 5 * 1000;
-
-    /**
-     * The default on whether to use TCP KeepAlive.
-     */
-    public static final boolean DEFAULT_TCP_KEEP_ALIVE = false;
-
-    /**
-     * The default on whether to throttle retries.
-     */
-    public static final boolean DEFAULT_THROTTLE_RETRIES = true;
-
-    /**
-     * The default on whether to cache response metadata.
-     */
-    public static final boolean DEFAULT_CACHE_RESPONSE_METADATA = true;
-
-    /**
-     * The default response metadata cache size.
-     */
-    public static final int DEFAULT_RESPONSE_METADATA_CACHE_SIZE = 50;
-
-    public static final int DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING = 100;
-
-
-    /** A prefix to the HTTP user agent header passed with all HTTP requests.  */
-    private String userAgentPrefix = DEFAULT_USER_AGENT;
-
-    /** A suffix to the HTTP user agent header. */
-    private String userAgentSuffix;
-
-    /**
-     * The maximum number of times that a retryable failed request (ex: a 5xx response from a
-     * service) will be retried. Or -1 if the user has not explicitly set this value, in which case
-     * the configured RetryPolicy will be used to control the retry count.
-     */
-    private int maxErrorRetry = -1;
-
-    /** The retry policy upon failed requests. **/
-    private RetryPolicy retryPolicy = DEFAULT_RETRY_POLICY;
-
-    /** Optionally specifies the local address to bind to */
-    private InetAddress localAddress;
-
-    /**
-     * The protocol to use when connecting to Amazon Web Services.
-     * <p>
-     * The default configuration is to use HTTPS for all requests for increased security.
-     */
-    private Protocol protocol = Protocol.HTTPS;
-
-    /** Optionally specifies the proxy host to connect through. */
-    private String proxyHost = null;
-
-    /** Optionally specifies the port on the proxy host to connect through. */
-    private int proxyPort = -1;
-
-    /** Optionally specifies the user name to use when connecting through a proxy. */
-    private String proxyUsername = null;
-
-    /** Optionally specifies the password to use when connecting through a proxy. */
-    private String proxyPassword = null;
-
-    /** Optional Windows domain name for configuring NTLM proxy support. */
-    private String proxyDomain = null;
-
-    /** Optional Windows workstation name for configuring NTLM proxy support. */
-    private String proxyWorkstation = null;
-
-    /** Optional specifies the hosts that should be accessed without going through the proxy. */
-    private String nonProxyHosts = null;
-
-    /** Specifies the proxy authentication methods that should be used, in priority order. */
-    private List<ProxyAuthenticationMethod> proxyAuthenticationMethods = null;
-
-    /**
-     * Whether to pre-emptively authenticate against a proxy server using basic authentication
-     */
-    private boolean preemptiveBasicProxyAuth;
-
-    /** The maximum number of open HTTP connections. */
-    private int maxConnections = DEFAULT_MAX_CONNECTIONS;
-
-    /**
-     * The amount of time to wait (in milliseconds) for data to be transfered over an established,
-     * open connection before the connection is timed out. A value of 0 means infinity, and is not
-     * recommended.
-     */
-    private int socketTimeout = DEFAULT_SOCKET_TIMEOUT;
-
-    /**
-     * The amount of time to wait (in milliseconds) when initially establishing a connection before
-     * giving up and timing out. A value of 0 means infinity, and is not recommended.
-     */
-    private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
-
-    /**
-     * The amount of time to wait (in milliseconds) for a request to complete before giving up and
-     * timing out. A value of 0 means infinity. Consider setting this if a harder guarantee is
-     * required on the maximum amount of time a request will take for non-streaming operations, and
-     * are willing to spin up a background thread to enforce it.
-     */
-    private int requestTimeout = DEFAULT_REQUEST_TIMEOUT;
-
-    private int clientExecutionTimeout = DEFAULT_CLIENT_EXECUTION_TIMEOUT;
-
-    private boolean throttleRetries = DEFAULT_THROTTLE_RETRIES;
-
-    /**
-     * Optional size hint (in bytes) for the low level TCP send buffer. This is an advanced option
-     * for advanced users who want to tune low level TCP parameters to try and squeeze out more
-     * performance.
-     */
-    private int socketSendBufferSizeHint = 0;
-
-    /**
-     * Optional size hint (in bytes) for the low level TCP receive buffer. This is an advanced
-     * option for advanced users who want to tune low level TCP parameters to try and squeeze out
-     * more performance.
-     */
-    private int socketReceiveBufferSizeHint = 0;
-
-    /**
-     * Optional whether to use the {@link IdleConnectionReaper} to manage stale connections. A
-     * reason for not running the {@link IdleConnectionReaper} can be if running in an environment
-     * where the modifyThread and modifyThreadGroup permissions are not allowed.
-     */
-    private boolean useReaper = DEFAULT_USE_REAPER;
-
-    /**
-     * Optional whether to use gzip compression when making HTTP requests.
-     */
-    private boolean useGzip = DEFAULT_USE_GZIP;
-
-    /**
-     * Optional override to control which signature algorithm should be used to sign requests to the
-     * service. If not explicitly set, the client will determine the algorithm to use by inspecting
-     * a configuration file baked in to the SDK.
-     */
-    private String signerOverride;
-
-    /**
-     * Optional expiration time for a connection in the connection pool. When a connection is
-     * retrieved from the connection pool, this parameter is checked to see if the connection can be
-     * reused.
-     */
-    private long connectionTTL = DEFAULT_CONNECTION_TTL;
-
-    /**
-     * The maximum idle time for a connection in the connection pool.
-     */
-    private long connectionMaxIdleMillis = DEFAULT_CONNECTION_MAX_IDLE_MILLIS;
-
-    private int validateAfterInactivityMillis = DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS;
-
-    /**
-     * Optional override to enable support for TCP KeepAlive (not to be confused with HTTP
-     * KeepAlive). TCP KeepAlive can be used to detect misbehaving routers or down servers through
-     * the use of special, empty-data keep alive packets.
-     * <p>
-     * Actual TCP KeepAlive values (timeout, number of packets, etc) are configured via the
-     * operating system (sysctl on Linux, and Registry values on Windows).
-     */
-    private boolean tcpKeepAlive = DEFAULT_TCP_KEEP_ALIVE;
-
-    /**
-     * Whether or not to cache response metadata.
-     * <p>
-     * Response metadata is typically used for troubleshooting issues with AWS support staff when
-     * services aren't acting as expected.
-     * </p>
-     * <p>
-     * While this feature is useful for debugging it adds overhead and disabling it may
-     * be desired in high throughput applications.
-     * </p>
-     */
-    private boolean cacheResponseMetadata = DEFAULT_CACHE_RESPONSE_METADATA;
-
-    /**
-     * Size of the response metadata cache, if it is enabled.
-     * <p>
-     * Response metadata is typically used for troubleshooting issues with AWS support staff when
-     * services aren't acting as expected.
-     */
-    private int responseMetadataCacheSize = DEFAULT_RESPONSE_METADATA_CACHE_SIZE;
-
-    /**
-     * The DNS Resolver to resolve IP addresses of Amazon Web Services.
-     */
-    private DnsResolver dnsResolver = new SystemDefaultDnsResolver();
-
-    /**
-     * An instance of {@link SecureRandom} configured by the user; or the JDK default will be used
-     * if it is set to null or not explicitly configured.
-     */
-    private SecureRandom secureRandom;
-
-    /**
-     * Headers to be added to all requests
-     */
-    private Map<String, String> headers = new HashMap<String, String>();
-
-    /**
-     * Optional override to enable/disable support for HTTP/1.1 handshake utilizing EXPECT:
-     * 100-Continue. The default value is true.
-     * <p>
-     * The detail of HTTP Expect Continue is defined at
-     * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3"> Use of the 100
-     * (Continue) Status</a>. Setting this as false will reduce latency when you want to send small
-     * size of payload. It is highly recommended to use the default value if you want to transfer a
-     * large amount of data to the server, such as uploading a big file to S3 bucket.
-     */
-    private boolean useExpectContinue = DEFAULT_USE_EXPECT_CONTINUE;
-
-    /**
-     * The maximum number of throttled retries if the initial request
-     * fails.
-     */
-    private int maxConsecutiveRetriesBeforeThrottling = DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING;
-
-    /**
-     * Can be used to specify custom specific Apache HTTP client configurations.
-     */
-    private final ApacheHttpClientConfig apacheHttpClientConfig;
-
-    public ClientConfiguration() {
-        apacheHttpClientConfig = new ApacheHttpClientConfig();
-    }
-
-    public ClientConfiguration(ClientConfiguration other) {
-        this.connectionTimeout = other.getConnectionTimeout();
-        this.maxConnections = other.getMaxConnections();
-        this.maxErrorRetry = other.getMaxErrorRetry();
-        this.retryPolicy = other.getRetryPolicy();
-        this.throttleRetries = other.useThrottledRetries();
-        this.localAddress = other.getLocalAddress();
-        this.protocol = other.getProtocol();
-        this.proxyDomain = other.getProxyDomain();
-        this.proxyHost = other.getProxyHost();
-        this.proxyPassword = other.getProxyPassword();
-        this.proxyPort = other.getProxyPort();
-        this.proxyUsername = other.getProxyUsername();
-        this.proxyWorkstation = other.getProxyWorkstation();
-        this.nonProxyHosts = other.getNonProxyHosts();
-        this.proxyAuthenticationMethods = other.getProxyAuthenticationMethods();
-        this.preemptiveBasicProxyAuth = other.isPreemptiveBasicProxyAuth();
-        this.socketTimeout = other.getSocketTimeout();
-        this.requestTimeout = other.getRequestTimeout();
-        this.clientExecutionTimeout = other.getClientExecutionTimeout();
-        this.userAgentPrefix = other.getUserAgentPrefix();
-        this.userAgentSuffix = other.getUserAgentSuffix();
-        this.useReaper = other.useReaper();
-        this.useGzip = other.useGzip();
-        this.socketSendBufferSizeHint = other.getSocketBufferSizeHints()[0];
-        this.socketReceiveBufferSizeHint = other.getSocketBufferSizeHints()[1];
-        this.signerOverride = other.getSignerOverride();
-        this.responseMetadataCacheSize = other.getResponseMetadataCacheSize();
-        this.dnsResolver = other.getDnsResolver();
-        this.useExpectContinue = other.isUseExpectContinue();
-        this.apacheHttpClientConfig = new ApacheHttpClientConfig(other.getApacheHttpClientConfig());
-        this.cacheResponseMetadata = other.getCacheResponseMetadata();
-        this.connectionTTL = other.getConnectionTTL();
-        this.connectionMaxIdleMillis = other.getConnectionMaxIdleMillis();
-        this.validateAfterInactivityMillis = other.getValidateAfterInactivityMillis();
-        this.tcpKeepAlive = other.useTcpKeepAlive();
-        this.secureRandom = other.getSecureRandom();
-        this.headers.clear();
-        this.headers.putAll(other.getHeaders());
-        this.maxConsecutiveRetriesBeforeThrottling = other.getMaxConsecutiveRetriesBeforeThrottling();
-    }
-
-    /**
-     * Returns the protocol (HTTP or HTTPS) to use when connecting to Amazon Web Services.
-     * <p>
-     * The default configuration is to use HTTPS for all requests for increased security.
-     * <p>
-     * Individual clients can also override this setting by explicitly including the protocol as
-     * part of the endpoint URL when calling {@link AmazonWebServiceClient#setEndpoint(String)}.
-     *
-     * @return The protocol to use when connecting to Amazon Web Services.
-     */
-    public Protocol getProtocol() {
-        return protocol;
-    }
-
-    /**
-     * Sets the protocol (i.e. HTTP or HTTPS) to use when connecting to Amazon Web Services.
-     * <p>
-     * The default configuration is to use HTTPS for all requests for increased security.
-     * <p>
-     * Individual clients can also override this setting by explicitly including the protocol as
-     * part of the endpoint URL when calling {@link AmazonWebServiceClient#setEndpoint(String)}.
-     *
-     * @param protocol
-     *            The protocol to use when connecting to Amazon Web Services.
-     */
-    public void setProtocol(Protocol protocol) {
-        this.protocol = protocol;
-    }
-
-    /**
-     * Sets the protocol (i.e. HTTP or HTTPS) to use when connecting to Amazon Web Services, and
-     * returns the updated ClientConfiguration object so that additional calls may be chained
-     * together.
-     * <p>
-     * The default configuration is to use HTTPS for all requests for increased security.
-     * <p>
-     * Individual clients can also override this setting by explicitly including the protocol as
-     * part of the endpoint URL when calling {@link AmazonWebServiceClient#setEndpoint(String)}.
-     *
-     * @param protocol
-     *            The protocol to use when connecting to Amazon Web Services.
-     * @return The updated ClientConfiguration object with the new max HTTP connections setting.
-     */
-    public ClientConfiguration withProtocol(Protocol protocol) {
-        setProtocol(protocol);
-        return this;
-    }
-
-    /**
-     * Returns the maximum number of allowed open HTTP connections.
-     *
-     * @return The maximum number of allowed open HTTP connections.
-     */
-    public int getMaxConnections() {
-        return maxConnections;
-    }
-
-    /**
-     * Sets the maximum number of allowed open HTTP connections.
-     *
-     * @param maxConnections
-     *            The maximum number of allowed open HTTP connections.
-     */
-    public void setMaxConnections(int maxConnections) {
-        this.maxConnections = maxConnections;
-    }
-
-    /**
-     * Sets the maximum number of allowed open HTTP connections and returns the updated
-     * ClientConfiguration object.
-     *
-     * @param maxConnections
-     *            The maximum number of allowed open HTTP connections.
-     * @return The updated ClientConfiguration object with the new max HTTP connections setting.
-     */
-    public ClientConfiguration withMaxConnections(int maxConnections) {
-        setMaxConnections(maxConnections);
-        return this;
-    }
-
-    /**
-     * @deprecated Replaced by {@link #getUserAgentPrefix()} and {@link #getUserAgentSuffix()}
-     * @return The user agent string to use when sending requests.
-     */
-    @Deprecated
-    public String getUserAgent() {
-        return getUserAgentPrefix();
-    }
-
-    /**
-     * @deprecated Replaced by {@link #setUserAgentPrefix(String)} and {@link #setUserAgentSuffix(String)}
-     * @param userAgent
-     *            The user agent string to use when sending requests.
-     */
-    @Deprecated
-    public void setUserAgent(String userAgent) {
-        setUserAgentPrefix(userAgent);
-    }
-
-    /**
-     * @deprecated Replaced by {@link #withUserAgentPrefix(String)} and {@link #withUserAgentSuffix(String)}
-     * @param userAgent
-     *            The user agent string to use when sending requests.
-     * @return The updated ClientConfiguration object.
-     */
-    @Deprecated
-    public ClientConfiguration withUserAgent(String userAgent) {
-        return withUserAgentPrefix(userAgent);
-    }
-
-    /**
-     * Returns the HTTP user agent header prefix to send with all requests.
-     *
-     * @return The user agent string prefix to use when sending requests.
-     */
-    public String getUserAgentPrefix() {
-        return userAgentPrefix;
-    }
-
-    /**
-     * Sets the HTTP user agent prefix to send with all requests.
-     *
-     * @param prefix
-     *            The string to prefix to user agent to use when sending requests.
-     */
-    public void setUserAgentPrefix(String prefix) {
-        this.userAgentPrefix = prefix;
-    }
-
-    /**
-     * Sets the HTTP user agent prefix header used in requests and returns the updated ClientConfiguration
-     * object.
-     *
-     * @param prefix
-     *            The string to prefix to user agent to use when sending requests.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withUserAgentPrefix(String prefix) {
-        setUserAgentPrefix(prefix);
-        return this;
-    }
-
-    /**
-     * Returns the HTTP user agent header suffix to add to the end of the user agent header on all requests.
-     *
-     * @return The user agent string suffix to use when sending requests.
-     */
-    public String getUserAgentSuffix() {
-        return userAgentSuffix;
-    }
-
-    /**
-     * Sets the HTTP user agent suffix to send with all requests.
-     *
-     * @param suffix
-     *            The string to suffix to user agent to use when sending requests.
-     */
-    public void setUserAgentSuffix(String suffix) {
-        this.userAgentSuffix = suffix;
-    }
-
-    /**
-     * Sets the HTTP user agent suffix header used in requests and returns the updated ClientConfiguration
-     * object.
-     *
-     * @param suffix
-     *            The string to suffix to user agent to use when sending requests.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withUserAgentSuffix(String suffix) {
-        setUserAgentSuffix(suffix);
-        return this;
-    }
-
-    /**
-     * Returns the optional local address the client will bind to.
-     *
-     * @return The local address the client will bind to.
-     */
-    public InetAddress getLocalAddress() {
-        return localAddress;
-    }
-
-    /**
-     * Sets the optional local address the client will bind to.
-     *
-     * @param localAddress
-     *            The local address the client will bind to.
-     */
-    public void setLocalAddress(InetAddress localAddress) {
-        this.localAddress = localAddress;
-    }
-
-    /**
-     * Sets the optional local address the client will bind to and returns the updated
-     * ClientConfiguration object.
-     *
-     * @param localAddress
-     *            The local address the client will bind to.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withLocalAddress(InetAddress localAddress) {
-        setLocalAddress(localAddress);
-        return this;
-    }
-
-    /**
-     * Returns the value for the given system property.
-     */
-    private String getSystemProperty(String property) {
-        return System.getProperty(property);
-    }
-
-    /**
-     * Returns the Java system property for proxy host depending on
-     * {@link #getProtocol()}: i.e. if protocol is https, returns
-     * the value of the system property https.proxyHost, otherwise
-     * returns value of http.proxyHost.
-     */
-    private String getProxyHostProperty() {
-        return getProtocol() == Protocol.HTTPS
-                ? getSystemProperty("https.proxyHost")
-                : getSystemProperty("http.proxyHost");
-    }
-
-    /**
-     * Returns the optional proxy host the client will connect
-     * through.  Returns either the proxyHost set on this object, or
-     * if not provided, checks the value of the Java system property
-     * for proxy host according to {@link #getProtocol()}: i.e. if
-     * protocol is https, returns the value of the system property
-     * https.proxyHost, otherwise returns value of http.proxyHost.
-     *
-     * @return The proxy host the client will connect through.
-     */
-    public String getProxyHost() {
-        return (proxyHost != null) ? proxyHost : getProxyHostProperty();
-    }
-
-    /**
-     * Sets the optional proxy host the client will connect through.
-     *
-     * @param proxyHost
-     *            The proxy host the client will connect through.
-     */
-    public void setProxyHost(String proxyHost) {
-        this.proxyHost = proxyHost;
-    }
-
-    /**
-     * Sets the optional proxy host the client will connect through and returns the updated
-     * ClientConfiguration object.
-     *
-     * @param proxyHost
-     *            The proxy host the client will connect through.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyHost(String proxyHost) {
-        setProxyHost(proxyHost);
-        return this;
-    }
-
-    /**
-     * Returns the Java system property for proxy port depending on
-     * {@link #getProtocol()}: i.e. if protocol is https, returns
-     * the value of the system property https.proxyPort, otherwise
-     * returns value of http.proxyPort.  Defaults to {@link this.proxyPort}
-     * if the system property is not set with a valid port number.
-     */
-    private int getProxyPortProperty() {
-        final String proxyPortString = (getProtocol() == Protocol.HTTPS)
-                    ? getSystemProperty("https.proxyPort")
-                    : getSystemProperty("http.proxyPort");
-        try {
-            return Integer.parseInt(proxyPortString);
-        } catch (NumberFormatException e) {
-            return proxyPort;
-        }
-    }
-
-    /**
-     * Returns the optional proxy port the client will connect
-     * through.  Returns either the proxyPort set on this object, or
-     * if not provided, checks the value of the Java system property
-     * for proxy port according to {@link #getProtocol()}: i.e. if
-     * protocol is https, returns the value of the system property
-     * https.proxyPort, otherwise returns value of http.proxyPort.
-     *
-     * @return The proxy port the client will connect through.
-     */
-    public int getProxyPort() {
-        return (proxyPort >= 0) ? proxyPort : getProxyPortProperty();
-    }
-
-    /**
-     * Sets the optional proxy port the client will connect through.
-     *
-     * @param proxyPort
-     *            The proxy port the client will connect through.
-     */
-    public void setProxyPort(int proxyPort) {
-        this.proxyPort = proxyPort;
-    }
-
-    /**
-     * Sets the optional proxy port the client will connect through and returns the updated
-     * ClientConfiguration object.
-     *
-     * @param proxyPort
-     *            The proxy port the client will connect through.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyPort(int proxyPort) {
-        setProxyPort(proxyPort);
-        return this;
-    }
-
-    /**
-     * Returns the Java system property for proxy user name depending on
-     * {@link #getProtocol()}: i.e. if protocol is https, returns
-     * the value of the system property https.proxyUser, otherwise
-     * returns value of http.proxyUser.
-     */
-    private String getProxyUsernameProperty() {
-        return (getProtocol() == Protocol.HTTPS)
-                ? getSystemProperty("https.proxyUser")
-                : getSystemProperty("http.proxyUser");
-    }
-
-    /**
-     * Returns the optional proxy user name to use if connecting
-     * through a proxy.  Returns either the proxyUsername set on this
-     * object, or if not provided, checks the value of the Java system
-     * property for proxy user name according to {@link #getProtocol()}:
-     * i.e. if protocol is https, returns the value of the system
-     * property https.proxyUser, otherwise returns value of
-     * http.proxyUser.
-     *
-     * @return The optional proxy user name the configured client will use if connecting through a
-     *         proxy.
-     */
-    public String getProxyUsername() {
-        return (proxyUsername != null) ? proxyUsername : getProxyUsernameProperty();
-    }
-
-    /**
-     * Sets the optional proxy user name to use if connecting through a proxy.
-     *
-     * @param proxyUsername
-     *            The proxy user name to use if connecting through a proxy.
-     */
-    public void setProxyUsername(String proxyUsername) {
-        this.proxyUsername = proxyUsername;
-    }
-
-    /**
-     * Sets the optional proxy user name and returns the updated ClientConfiguration object.
-     *
-     * @param proxyUsername
-     *            The proxy user name to use if connecting through a proxy.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyUsername(String proxyUsername) {
-        setProxyUsername(proxyUsername);
-        return this;
-    }
-
-    /**
-     * Returns the Java system property for proxy password depending on
-     * {@link #getProtocol()}: i.e. if protocol is https, returns
-     * the value of the system property https.proxyPassword, otherwise
-     * returns value of http.proxyPassword.
-     */
-    private String getProxyPasswordProperty() {
-        return (getProtocol() == Protocol.HTTPS)
-                ? getSystemProperty("https.proxyPassword")
-                : getSystemProperty("http.proxyPassword");
-    }
-
-    /**
-     * Returns the optional proxy password to use if connecting
-     * through a proxy.  Returns either the proxyPassword set on this
-     * object, or if not provided, checks the value of the Java system
-     * property for proxy password according to {@link #getProtocol()}:
-     * i.e. if protocol is https, returns the value of the system
-     * property https.proxyPassword, otherwise returns value of
-     * http.proxyPassword.
-     *
-     * @return The password to use when connecting through a proxy.
-     */
-    public String getProxyPassword() {
-        return (proxyPassword != null) ? proxyPassword : getProxyPasswordProperty();
-    }
-
-    /**
-     * Sets the optional proxy password to use when connecting through a proxy.
-     *
-     * @param proxyPassword
-     *            The password to use when connecting through a proxy.
-     */
-    public void setProxyPassword(String proxyPassword) {
-        this.proxyPassword = proxyPassword;
-    }
-
-    /**
-     * Sets the optional proxy password to use when connecting through a proxy, and returns the
-     * updated ClientConfiguration object.
-     *
-     * @param proxyPassword
-     *            The password to use when connecting through a proxy.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyPassword(String proxyPassword) {
-        setProxyPassword(proxyPassword);
-        return this;
-    }
-
-    /**
-     * Returns the optional Windows domain name for configuring an NTLM proxy. If you aren't using a
-     * Windows NTLM proxy, you do not need to set this field.
-     *
-     * @return The optional Windows domain name for configuring an NTLM proxy.
-     */
-    public String getProxyDomain() {
-        return proxyDomain;
-    }
-
-    /**
-     * Sets the optional Windows domain name for configuration an NTLM proxy. If you aren't using a
-     * Windows NTLM proxy, you do not need to set this field.
-     *
-     * @param proxyDomain
-     *            The optional Windows domain name for configuring an NTLM proxy.
-     */
-    public void setProxyDomain(String proxyDomain) {
-        this.proxyDomain = proxyDomain;
-    }
-
-    /**
-     * Sets the optional Windows domain name for configuration an NTLM proxy and returns a reference
-     * to this updated ClientConfiguration object so that additional method calls can be chained
-     * together. If you aren't using a Windows NTLM proxy, you do not need to set this field.
-     *
-     * @param proxyDomain
-     *            The optional Windows domain name for configuring an NTLM proxy.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyDomain(String proxyDomain) {
-        setProxyDomain(proxyDomain);
-        return this;
-    }
-
-    /**
-     * Returns the optional Windows workstation name for configuring NTLM proxy support. If you
-     * aren't using a Windows NTLM proxy, you do not need to set this field.
-     *
-     * @return The optional Windows workstation name for configuring NTLM proxy support.
-     */
-    public String getProxyWorkstation() {
-        return proxyWorkstation;
-    }
-
-    /**
-     * Sets the optional Windows workstation name for configuring NTLM proxy support. If you aren't
-     * using a Windows NTLM proxy, you do not need to set this field.
-     *
-     * @param proxyWorkstation
-     *            The optional Windows workstation name for configuring NTLM proxy support.
-     */
-    public void setProxyWorkstation(String proxyWorkstation) {
-        this.proxyWorkstation = proxyWorkstation;
-    }
-
-    /**
-     * Sets the optional Windows workstation name for configuring NTLM proxy support, and returns
-     * the updated ClientConfiguration object so that additional method calls can be chained
-     * together. If you aren't using a Windows NTLM proxy, you do not need to set this field.
-     *
-     * @param proxyWorkstation
-     *            The optional Windows workstation name for configuring NTLM proxy support.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyWorkstation(String proxyWorkstation) {
-        setProxyWorkstation(proxyWorkstation);
-        return this;
-    }
-
-    /**
-     * Returns the Java system property for nonProxyHosts. We still honor this property even
-     * {@link #getProtocol()} is https, see http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html.
-     */
-    private String getNonProxyHostsProperty() {
-        return getSystemProperty("http.nonProxyHosts");
-    }
-
-    /**
-     * Returns the optional hosts the client will access without going
-     * through the proxy. Returns either the nonProxyHosts set on this
-     * object, or if not provided, checks the value of the Java system property
-     * for nonProxyHosts according to {@link #getProtocol()}: i.e. if
-     * protocol is https, returns null, otherwise returns value of http.nonProxyHosts.
-     *
-     * @return The hosts the client will connect through bypassing the proxy.
-     */
-    public String getNonProxyHosts() {
-        return nonProxyHosts != null ? nonProxyHosts : getNonProxyHostsProperty();
-    }
-
-    /**
-     * Set the optional hosts the client will access without going
-     * through the proxy.
-     *
-     * @param nonProxyHosts
-     *            The hosts the client will access without going through the proxy.
-     */
-    public void setNonProxyHosts(String nonProxyHosts) {
-        this.nonProxyHosts = nonProxyHosts;
-    }
-
-    /**
-     * Set the optional hosts the client will access without going
-     * through the proxy.
-     *
-     * @param nonProxyHosts
-     *            The hosts the client will access without going through the proxy.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withNonProxyHosts(String nonProxyHosts) {
-        setNonProxyHosts(nonProxyHosts);
-        return this;
-    }
-
-    /**
-     * Returns the list of authentication methods that should be used when authenticating against an HTTP proxy, in the order they
-     * should be attempted.
-     *
-     * @return An unmodifiable view of the proxy authentication methods that should be attempted, in order.
-     */
-    public List<ProxyAuthenticationMethod> getProxyAuthenticationMethods() {
-        return this.proxyAuthenticationMethods;
-    }
-
-    /**
-     * Configure the list of authentication methods that should be used when authenticating against an HTTP proxy, in the order
-     * they should be attempted. Any methods not included in this list will not be attempted. If one authentication method fails,
-     * the next method will be attempted, until a working method is found (or all methods have been attempted).
-     *
-     * <p>Setting this value to null indicates using the default behavior, which is to try all authentication methods in an
-     * unspecified order.</p>
-     *
-     * @param proxyAuthenticationMethods The proxy authentication methods to be attempted, in the order they should be attempted.
-     */
-    public void setProxyAuthenticationMethods(List<ProxyAuthenticationMethod> proxyAuthenticationMethods) {
-        if(proxyAuthenticationMethods == null) {
-            this.proxyAuthenticationMethods = null;
-        } else {
-            ValidationUtils.assertNotEmpty(proxyAuthenticationMethods, "proxyAuthenticationMethods");
-            this.proxyAuthenticationMethods =
-                    Collections.unmodifiableList(new ArrayList<ProxyAuthenticationMethod>(proxyAuthenticationMethods));
-        }
-    }
-
-    /**
-     * Configure the list of authentication methods that should be used when authenticating against an HTTP proxy, in the order
-     * they should be attempted. Any methods not included in this list will not be attempted. If one authentication method fails,
-     * the next method will be attempted, until a working method is found (or all methods have been attempted).
-     *
-     * <p>Setting this value to null indicates using the default behavior, which is to try all authentication methods in an
-     * unspecified order.</p>
-     *
-     * @param proxyAuthenticationMethods The proxy authentication methods to be attempted, in the order they should be attempted.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withProxyAuthenticationMethods(List<ProxyAuthenticationMethod> proxyAuthenticationMethods) {
-        setProxyAuthenticationMethods(proxyAuthenticationMethods);
-        return this;
-    }
-
-    /**
-     * Returns the retry policy upon failed requests.
-     *
-     * @return The retry policy upon failed requests.
-     */
-    public RetryPolicy getRetryPolicy() {
-        return retryPolicy;
-    }
-
-    /**
-     * Sets the retry policy upon failed requests. User could specify whether the RetryPolicy should
-     * honor maxErrorRetry set by {@link #setMaxErrorRetry(int)}.
-     *
-     * @param retryPolicy
-     *            The retry policy upon failed requests.
-     */
-    public void setRetryPolicy(RetryPolicy retryPolicy) {
-        this.retryPolicy = retryPolicy;
-    }
-
-    /**
-     * Sets the retry policy upon failed requests, and returns the updated ClientConfiguration
-     * object. User could specify whether the RetryPolicy should honor maxErrorRetry set by
-     * {@link #setMaxErrorRetry(int)}
-     *
-     * @param retryPolicy
-     *            The retry policy upon failed requests.
-     */
-    public ClientConfiguration withRetryPolicy(RetryPolicy retryPolicy) {
-        setRetryPolicy(retryPolicy);
-        return this;
-    }
-
-    /**
-     * Returns the maximum number of retry attempts for failed retryable requests (ex: 5xx error
-     * responses from a service). This method returns -1 before a maxErrorRetry value is explicitly
-     * set by {@link #setMaxErrorRetry(int)}, in which case the configured RetryPolicy will be used
-     * to control the retry count.
-     *
-     * @return The maximum number of retry attempts for failed retryable requests, or -1 if
-     *         maxErrorRetry has not been set by {@link #setMaxErrorRetry(int)}.
-     */
-    public int getMaxErrorRetry() {
-        return maxErrorRetry;
-    }
-
-    /**
-     * Sets the maximum number of retry attempts for failed retryable requests (ex: 5xx error
-     * responses from services).
-     *
-     * @param maxErrorRetry
-     *            The maximum number of retry attempts for failed retryable requests. This value
-     *            should not be negative.
-     */
-    public void setMaxErrorRetry(int maxErrorRetry) {
-        if (maxErrorRetry < 0) {
-            throw new IllegalArgumentException("maxErrorRetry shoud be non-negative");
-        }
-        this.maxErrorRetry = maxErrorRetry;
-    }
-
-    /**
-     * Sets the maximum number of retry attempts for failed retryable requests (ex: 5xx error
-     * responses from services), and returns the updated ClientConfiguration object.
-     *
-     * @param maxErrorRetry
-     *            The maximum number of retry attempts for failed retryable requests. This value
-     *            should not be negative.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withMaxErrorRetry(int maxErrorRetry) {
-        setMaxErrorRetry(maxErrorRetry);
-        return this;
-    }
-
-    /**
-     * Returns the amount of time to wait (in milliseconds) for data to be transfered over an
-     * established, open connection before the connection times out and is closed. A value of 0
-     * means infinity, and isn't recommended.
-     *
-     * @return The amount of time to wait (in milliseconds) for data to be transfered over an
-     *         established, open connection before the connection times out and is closed.
-     */
-    public int getSocketTimeout() {
-        return socketTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) for data to be transfered over an
-     * established, open connection before the connection times out and is closed. A value of 0
-     * means infinity, and isn't recommended.
-     *
-     * @param socketTimeout
-     *            The amount of time to wait (in milliseconds) for data to be transfered over an
-     *            established, open connection before the connection times out and is closed.
-     */
-    public void setSocketTimeout(int socketTimeout) {
-        this.socketTimeout = socketTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) for data to be transfered over an
-     * established, open connection before the connection times out and is closed, and returns the
-     * updated ClientConfiguration object so that additional method calls may be chained together.
-     *
-     * @param socketTimeout
-     *            The amount of time to wait (in milliseconds) for data to be transfered over an
-     *            established, open connection before the connection times out and is closed.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withSocketTimeout(int socketTimeout) {
-        setSocketTimeout(socketTimeout);
-        return this;
-    }
-
-    /**
-     * Returns the amount of time to wait (in milliseconds) when initially establishing a connection
-     * before giving up and timing out. A value of 0 means infinity, and is not recommended.
-     *
-     * @return The amount of time to wait (in milliseconds) when initially establishing a connection
-     *         before giving up and timing out.
-     */
-    public int getConnectionTimeout() {
-        return connectionTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) when initially establishing a connection
-     * before giving up and timing out. A value of 0 means infinity, and is not recommended.
-     *
-     * @param connectionTimeout
-     *            The amount of time to wait (in milliseconds) when initially establishing a
-     *            connection before giving up and timing out.
-     */
-    public void setConnectionTimeout(int connectionTimeout) {
-        this.connectionTimeout = connectionTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) when initially establishing a connection
-     * before giving up and timing out, and returns the updated ClientConfiguration object so that
-     * additional method calls may be chained together.
-     *
-     * @param connectionTimeout
-     *            the amount of time to wait (in milliseconds) when initially establishing a
-     *            connection before giving up and timing out.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withConnectionTimeout(int connectionTimeout) {
-        setConnectionTimeout(connectionTimeout);
-        return this;
-    }
-
-    /**
-     * Returns the amount of time to wait (in milliseconds) for the request to complete before
-     * giving up and timing out. A non-positive value disables this feature.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The request timeout feature doesn't have strict guarantees on how quickly a request is
-     * aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this, the request timeout feature
-     * should not be used when absolute precision is needed.
-     * </p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @return The amount of time to wait (in milliseconds) for the request to complete before
-     *         giving up and timing out.
-     * @see {@link ClientConfiguration#setClientExecutionTimeout(int)} to enforce a timeout across
-     *      all retries
-     */
-    public int getRequestTimeout() {
-        return requestTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) for the request to complete before giving
-     * up and timing out. A non-positive value disables this feature.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The request timeout feature doesn't have strict guarantees on how quickly a request is
-     * aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this, the request timeout feature
-     * should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param requestTimeout
-     *            The amount of time to wait (in milliseconds) for the request to complete before
-     *            giving up and timing out.
-     * @see {@link ClientConfiguration#setClientExecutionTimeout(int)} to enforce a timeout across
-     *      all retries
-     */
-    public void setRequestTimeout(int requestTimeout) {
-        this.requestTimeout = requestTimeout;
-    }
-
-    /**
-     * Sets the amount of time to wait (in milliseconds) for the request to complete before giving
-     * up and timing out. A non-positive value disables this feature. Returns the updated
-     * ClientConfiguration object so that additional method calls may be chained together.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The request timeout feature doesn't have strict guarantees on how quickly a request is
-     * aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this, the request timeout feature
-     * should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param requestTimeout
-     *            The amount of time to wait (in milliseconds) for the request to complete before
-     *            giving up and timing out.
-     * @return The updated ClientConfiguration object.
-     * @see {@link ClientConfiguration#setClientExecutionTimeout(int)} to enforce a timeout across
-     *      all retries
-     */
-    public ClientConfiguration withRequestTimeout(int requestTimeout) {
-        setRequestTimeout(requestTimeout);
-        return this;
-    }
-
-    /**
-     * Returns the amount of time (in milliseconds) to allow the client to complete the execution of
-     * an API call. This timeout covers the entire client execution except for marshalling. This
-     * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The client execution timeout feature doesn't have strict guarantees on how quickly a request
-     * is aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this, the client execution timeout
-     * feature should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * This may be used together with {@link ClientConfiguration#setRequestTimeout(int)} to enforce
-     * both a timeout on each individual HTTP request (i.e. each retry) and the total time spent on
-     * all requests across retries (i.e. the 'client execution' time). A non-positive value disables
-     * this feature.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @return The amount of time (in milliseconds) to allow the client to complete the execution of
-     *         an API call.
-     * @see {@link ClientConfiguration#setRequestTimeout(int)} to enforce a timeout per HTTP request
-     */
-    public int getClientExecutionTimeout() {
-        return this.clientExecutionTimeout;
-    }
-
-    /**
-     * Sets the amount of time (in milliseconds) to allow the client to complete the execution of
-     * an API call. This timeout covers the entire client execution except for marshalling. This
-     * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The client execution timeout feature doesn't have strict guarantees on how quickly a request
-     * is aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this, the client execution timeout
-     * feature should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * This may be used together with {@link ClientConfiguration#setRequestTimeout(int)} to enforce
-     * both a timeout on each individual HTTP request (i.e. each retry) and the total time spent on
-     * all requests across retries (i.e. the 'client execution' time). A non-positive value disables
-     * this feature.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param clientExecutionTimeout
-     *            The amount of time (in milliseconds) to allow the client to complete the execution
-     *            of an API call. A value of '0' disables this feature.
-     * @see {@link ClientConfiguration#setRequestTimeout(int)} to enforce a timeout per HTTP request
-     */
-    public void setClientExecutionTimeout(int clientExecutionTimeout) {
-        this.clientExecutionTimeout = clientExecutionTimeout;
-    }
-
-    /**
-     * Sets the amount of time (in milliseconds) to allow the client to complete the execution of
-     * an API call. This timeout covers the entire client execution except for marshalling. This
-     * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
-     * <p>
-     * This feature requires buffering the entire response (for non-streaming APIs) into memory to
-     * enforce a hard timeout when reading the response. For APIs that return large responses this
-     * could be expensive.
-     * <p>
-     * <p>
-     * The client execution timeout feature doesn't have strict guarantees on how quickly a request
-     * is aborted when the timeout is breached. The typical case aborts the request within a few
-     * milliseconds but there may occasionally be requests that don't get aborted until several
-     * seconds after the timer has been breached. Because of this, the client execution timeout
-     * feature should not be used when absolute precision is needed.
-     * </p>
-     * <p>
-     * This may be used together with {@link ClientConfiguration#setRequestTimeout(int)} to enforce
-     * both a timeout on each individual HTTP request (i.e. each retry) and the total time spent on
-     * all requests across retries (i.e. the 'client execution' time). A non-positive value disables
-     * this feature.
-     * </p>
-     * <p>
-     * <b>Note:</b> This feature is not compatible with Java 1.6.
-     * </p>
-     *
-     * @param clientExecutionTimeout
-     *            The amount of time (in milliseconds) to allow the client to complete the execution
-     *            of an API call. A value of '0' disables this feature.
-     * @return The updated ClientConfiguration object for method chaining
-     * @see {@link ClientConfiguration#setRequestTimeout(int)} to enforce a timeout per HTTP request
-     */
-    public ClientConfiguration withClientExecutionTimeout(int clientExecutionTimeout) {
-        setClientExecutionTimeout(clientExecutionTimeout);
-        return this;
-    }
-
-    /**
-     * Checks if the {@link IdleConnectionReaper} is to be started
-     *
-     * @return if the {@link IdleConnectionReaper} is to be started
-     */
-    public boolean useReaper() {
-        return useReaper;
-    }
-
-    /**
-     * Sets whether the {@link IdleConnectionReaper} is to be started as a daemon thread
-     *
-     * @param use
-     *            whether the {@link IdleConnectionReaper} is to be started as a daemon thread
-     * @see IdleConnectionReaper
-     */
-    public void setUseReaper(boolean use) {
-        this.useReaper = use;
-    }
-
-    /**
-     * Sets whether the {@link IdleConnectionReaper} is to be started as a daemon thread
-     *
-     * @param use
-     *            the {@link IdleConnectionReaper} is to be started as a daemon thread
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withReaper(boolean use) {
-        setUseReaper(use);
-        return this;
-    }
-
-    /**
-     * Returns whether retry throttling will be used.
-     * <p>
-     * Retry throttling is a feature which intelligently throttles retry attempts when a
-     * large percentage of requests are failing and retries are unsuccessful, particularly
-     * in scenarios of degraded service health.  In these situations the client will drain its
-     * internal retry capacity and slowly roll off from retry attempts until requests begin
-     * to succeed again.  At that point the retry capacity pool will begin to refill and
-     * retries will once again be permitted.
-     * </p>
-     * <p>
-     * In situations where retries have been throttled this feature will effectively result in
-     * fail-fast behavior from the client.  Because retries are circumvented exceptions will
-     * be immediately returned to the caller if the initial request is unsuccessful.  This
-     * will result in a greater number of exceptions being returned up front but prevents
-     * requests being tied up attempting subsequent retries which are also likely to fail.
-     * </p>
-     *
-     * @return true if retry throttling will be used
-     */
-    public boolean useThrottledRetries() {
-        return throttleRetries || getSystemProperty(
-                SDKGlobalConfiguration.RETRY_THROTTLING_SYSTEM_PROPERTY) != null;
-    }
-
-    /**
-     * Sets whether throttled retries should be used
-     * <p>
-     * Retry throttling is a feature which intelligently throttles retry attempts when a
-     * large percentage of requests are failing and retries are unsuccessful, particularly
-     * in scenarios of degraded service health.  In these situations the client will drain its
-     * internal retry capacity and slowly roll off from retry attempts until requests begin
-     * to succeed again.  At that point the retry capacity pool will begin to refill and
-     * retries will once again be permitted.
-     * </p>
-     * <p>
-     * In situations where retries have been throttled this feature will effectively result in
-     * fail-fast behavior from the client.  Because retries are circumvented exceptions will
-     * be immediately returned to the caller if the initial request is unsuccessful.  This
-     * will result in a greater number of exceptions being returned up front but prevents
-     * requests being tied up attempting subsequent retries which are also likely to fail.
-     * </p>
-     *
-     * @param use
-     *            true if throttled retries should be used
-     */
-    public void setUseThrottleRetries(boolean use) { this.throttleRetries = use; }
-
-    /**
-     * Sets whether throttled retries should be used
-     * <p>
-     * Retry throttling is a feature which intelligently throttles retry attempts when a
-     * large percentage of requests are failing and retries are unsuccessful, particularly
-     * in scenarios of degraded service health.  In these situations the client will drain its
-     * internal retry capacity and slowly roll off from retry attempts until requests begin
-     * to succeed again.  At that point the retry capacity pool will begin to refill and
-     * retries will once again be permitted.
-     * </p>
-     * <p>
-     * In situations where retries have been throttled this feature will effectively result in
-     * fail-fast behavior from the client.  Because retries are circumvented exceptions will
-     * be immediately returned to the caller if the initial request is unsuccessful.  This
-     * will result in a greater number of exceptions being returned up front but prevents
-     * requests being tied up attempting subsequent retries which are also likely to fail.
-     * </p>
-
-     * @param use
-     *            true if throttled retries should be used
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withThrottledRetries(boolean use) {
-        setUseThrottleRetries(use);
-        return this;
-    }
-
-    /**
-     * Set the maximum number of consecutive failed retries that the client will permit before
-     * throttling all subsequent retries of failed requests.
-     * <p>
-     * Note: This does not guarantee that each failed request will be retried up to this many times.
-     * Depending on the configured {@link RetryPolicy} and the number of past failed and successful
-     * requests, the actual number of retries attempted may be less.
-     * <p>
-     * This has a default value of {@link #DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING}.
-     *
-     * @param maxConsecutiveRetriesBeforeThrottling The maximum number of consecutive retries.
-     */
-    public void setMaxConsecutiveRetriesBeforeThrottling(int maxConsecutiveRetriesBeforeThrottling) {
-        this.maxConsecutiveRetriesBeforeThrottling = ValidationUtils.assertIsPositive(maxConsecutiveRetriesBeforeThrottling,
-                "maxConsecutiveRetriesBeforeThrottling");
-    }
-    /**
-     * Set the maximum number of consecutive failed retries that the client will permit before
-     * throttling all subsequent retries of failed requests.
-     * <p>
-     * Note: This does not guarantee that each failed request will be retried up to this many times.
-     * Depending on the configured {@link RetryPolicy} and the number of past failed and successful
-     * requests, the actual number of retries attempted may be less.
-     * <p>
-     * This has a default value of {@link #DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING}.
-     *
-     * @param maxConsecutiveRetriesBeforeThrottling The maximum number of consecutive retries.
-     *
-     * @return This object for chaining.
-     */
-    public ClientConfiguration withMaxConsecutiveRetriesBeforeThrottling(int maxConsecutiveRetriesBeforeThrottling) {
-        setMaxConsecutiveRetriesBeforeThrottling(maxConsecutiveRetriesBeforeThrottling);
-        return this;
-    }
-
-    /**
-     * @return Set the maximum number of consecutive failed retries that the client will permit
-     * before throttling all subsequent retries of failed requests.
-     */
-    public int getMaxConsecutiveRetriesBeforeThrottling() {
-        return maxConsecutiveRetriesBeforeThrottling;
-    }
-
-    /**
-     * Checks if gzip compression is used
-     *
-     * @return if gzip compression is used
-     */
-    public boolean useGzip() {
-        return useGzip;
-    }
-
-    /**
-     * Sets whether gzip compression should be used
-     *
-     * @param use
-     *            whether gzip compression should be used
-     */
-    public void setUseGzip(boolean use) {
-        this.useGzip = use;
-    }
-
-    /**
-     * Sets whether gzip compression should be used
-     *
-     * @param use
-     *            whether gzip compression should be used
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withGzip(boolean use) {
-        setUseGzip(use);
-        return this;
-    }
-
-    /**
-     * Returns the optional size hints (in bytes) for the low level TCP send and receive buffers.
-     * This is an advanced option for advanced users who want to tune low level TCP parameters to
-     * try and squeeze out more performance.
-     * <p>
-     * The optimal TCP buffer sizes for a particular application are highly dependent on network
-     * configuration and operating system configuration and capabilities. For example, most modern
-     * operating systems provide auto-tuning functionality for TCP buffer sizes, which can have a
-     * big impact on performance for TCP connections that are held open long enough for the
-     * auto-tuning to optimize buffer sizes.
-     * <p>
-     * Large buffer sizes (ex: 2MB) will allow the operating system to buffer more data in memory
-     * without requiring the remote server to acknowledge receipt of that information, so can be
-     * particularly useful when the network has high latency.
-     * <p>
-     * This is only a <b>hint</b>, and the operating system may choose not to honor it. When using
-     * this option, users should <b>always</b> check the operating system's configured limits and
-     * defaults. Most OS's have a maximum TCP buffer size limit configured, and won't let you go
-     * beyond that limit unless you explicitly raise the max TCP buffer size limit.
-     * <p>
-     * There are many resources available online to help with configuring TCP buffer sizes and
-     * operating system specific TCP settings, including:
-     * <ul>
-     * <li>http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html</li>
-     * <li>http://fasterdata.es.net/TCP-tuning/</li>
-     * </ul>
-     *
-     * @return A two element array containing first the TCP send buffer size hint and then the TCP
-     *         receive buffer size hint.
-     */
-    public int[] getSocketBufferSizeHints() {
-        return new int[] { socketSendBufferSizeHint, socketReceiveBufferSizeHint };
-    }
-
-    /**
-     * Sets the optional size hints (in bytes) for the low level TCP send and receive buffers. This
-     * is an advanced option for advanced users who want to tune low level TCP parameters to try and
-     * squeeze out more performance.
-     * <p>
-     * The optimal TCP buffer sizes for a particular application are highly dependent on network
-     * configuration and operating system configuration and capabilities. For example, most modern
-     * operating systems provide auto-tuning functionality for TCP buffer sizes, which can have a
-     * big impact on performance for TCP connections that are held open long enough for the
-     * auto-tuning to optimize buffer sizes.
-     * <p>
-     * Large buffer sizes (ex: 2MB) will allow the operating system to buffer more data in memory
-     * without requiring the remote server to acknowledge receipt of that information, so can be
-     * particularly useful when the network has high latency.
-     * <p>
-     * This is only a <b>hint</b>, and the operating system may choose not to honor it. When using
-     * this option, users should <b>always</b> check the operating system's configured limits and
-     * defaults. Most OS's have a maximum TCP buffer size limit configured, and won't let you go
-     * beyond that limit unless you explicitly raise the max TCP buffer size limit.
-     * <p>
-     * There are many resources available online to help with configuring TCP buffer sizes and
-     * operating system specific TCP settings, including:
-     * <ul>
-     * <li>http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html</li>
-     * <li>http://fasterdata.es.net/TCP-tuning/</li>
-     * </ul>
-     *
-     * @param socketSendBufferSizeHint
-     *            The size hint (in bytes) for the low level TCP send buffer.
-     * @param socketReceiveBufferSizeHint
-     *            The size hint (in bytes) for the low level TCP receive buffer.
-     */
-    public void setSocketBufferSizeHints(int socketSendBufferSizeHint, int socketReceiveBufferSizeHint) {
-        this.socketSendBufferSizeHint = socketSendBufferSizeHint;
-        this.socketReceiveBufferSizeHint = socketReceiveBufferSizeHint;
-    }
-
-    /**
-     * Sets the optional size hints (in bytes) for the low level TCP send and receive buffers, and
-     * returns the updated ClientConfiguration object so that additional method calls may be chained
-     * together.
-     * <p>
-     * This is an advanced option for advanced users who want to tune low level TCP parameters to
-     * try and squeeze out more performance.
-     * <p>
-     * The optimal TCP buffer sizes for a particular application are highly dependent on network
-     * configuration and operating system configuration and capabilities. For example, most modern
-     * operating systems provide auto-tuning functionality for TCP buffer sizes, which can have a
-     * big impact on performance for TCP connections that are held open long enough for the
-     * auto-tuning to optimize buffer sizes.
-     * <p>
-     * Large buffer sizes (ex: 2MB) will allow the operating system to buffer more data in memory
-     * without requiring the remote server to acknowledge receipt of that information, so can be
-     * particularly useful when the network has high latency.
-     * <p>
-     * This is only a <b>hint</b>, and the operating system may choose not to honor it. When using
-     * this option, users should <b>always</b> check the operating system's configured limits and
-     * defaults. Most OS's have a maximum TCP buffer size limit configured, and won't let you go
-     * beyond that limit unless you explicitly raise the max TCP buffer size limit.
-     * <p>
-     * There are many resources available online to help with configuring TCP buffer sizes and
-     * operating system specific TCP settings, including:
-     * <ul>
-     * <li>http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html</li>
-     * <li>http://fasterdata.es.net/TCP-tuning/</li>
-     * </ul>
-     *
-     * @param socketSendBufferSizeHint
-     *            The size hint (in bytes) for the low level TCP send buffer.
-     * @param socketReceiveBufferSizeHint
-     *            The size hint (in bytes) for the low level TCP receive buffer.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withSocketBufferSizeHints(int socketSendBufferSizeHint,
-                                                         int socketReceiveBufferSizeHint) {
-        setSocketBufferSizeHints(socketSendBufferSizeHint, socketReceiveBufferSizeHint);
-        return this;
-    }
-
-    /**
-     * Returns the name of the signature algorithm to use for signing requests made by this client.
-     * If not set or explicitly set to null, the client will choose a signature algorithm to use
-     * based on a configuration file of supported signature algorithms for the service and region.
-     * <p>
-     * Most users do not need to concern themselves with which signature algorithm is being used, as
-     * the defaults will be sufficient. This setting exists only so advanced users can opt in to
-     * newer signature protocols which have not yet been made the default for a particular
-     * service/region.
-     * <p>
-     * Not all services support all signature algorithms, and configuring an unsupported signature
-     * algorithm will lead to authentication failures. Use me at your own risk, and only after
-     * consulting the documentation for the service to ensure it actually does supports your chosen
-     * algorithm.
-     * <p>
-     * If non-null, the name returned from this method is used to look up a {@code Signer} class
-     * implementing the chosen algorithm by the {@code com.amazonaws.auth.SignerFactory} class.
-     *
-     * @return The signature algorithm to use for this client, or null to use the default.
-     */
-    public String getSignerOverride() {
-        return signerOverride;
-    }
-
-    /**
-     * Sets the name of the signature algorithm to use for signing requests made by this client. If
-     * not set or explicitly set to null, the client will choose a signature algorithm to use based
-     * on a configuration file of supported signature algorithms for the service and region.
-     * <p>
-     * Most users do not need to concern themselves with which signature algorithm is being used, as
-     * the defaults will be sufficient. This setting exists only so advanced users can opt in to
-     * newer signature protocols which have not yet been made the default for a particular
-     * service/region.
-     * <p>
-     * Not all services support all signature algorithms, and configuring an unsupported signature
-     * algorithm will lead to authentication failures. Use me at your own risk, and only after
-     * consulting the documentation for the service to ensure it actually does supports your chosen
-     * algorithm.
-     * <p>
-     * If non-null, the name returned from this method is used to look up a {@code Signer} class
-     * implementing the chosen algorithm by the {@code com.amazonaws.auth.SignerFactory} class.
-     *
-     * @param value
-     *            The signature algorithm to use for this client, or null to use the default.
-     */
-    public void setSignerOverride(final String value) {
-        signerOverride = value;
-    }
-
-    /**
-     * Sets the name of the signature algorithm to use for signing requests made by this client. If
-     * not set or explicitly set to null, the client will choose a signature algorithm to use based
-     * on a configuration file of supported signature algorithms for the service and region.
-     * <p>
-     * Most users do not need to concern themselves with which signature algorithm is being used, as
-     * the defaults will be sufficient. This setting exists only so advanced users can opt in to
-     * newer signature protocols which have not yet been made the default for a particular
-     * service/region.
-     * <p>
-     * Not all services support all signature algorithms, and configuring an unsupported signature
-     * algorithm will lead to authentication failures. Use me at your own risk, and only after
-     * consulting the documentation for the service to ensure it actually does supports your chosen
-     * algorithm.
-     * <p>
-     * If non-null, the name returned from this method is used to look up a {@code Signer} class
-     * implementing the chosen algorithm by the {@code com.amazonaws.auth.SignerFactory} class.
-     *
-     * @param value
-     *            The signature algorithm to use for this client, or null to use the default.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withSignerOverride(final String value) {
-        setSignerOverride(value);
-        return this;
-    }
-
-    /**
-     * Returns whether to attempt to authenticate preemptively against proxy servers using basic
-     * authentication
-     *
-     * @return Whether to authenticate preemptively against proxy server.
-     */
-    public boolean isPreemptiveBasicProxyAuth() {
-        return preemptiveBasicProxyAuth;
-    }
-
-    /**
-     * Sets whether to attempt to authenticate preemptively against proxy servers using basic
-     * authentication
-     *
-     * @param preemptiveBasicProxyAuth
-     *            Whether to authenticate preemptively against proxy server.
-     */
-    public void setPreemptiveBasicProxyAuth(Boolean preemptiveBasicProxyAuth) {
-        this.preemptiveBasicProxyAuth = preemptiveBasicProxyAuth;
-    }
-
-    /**
-     * Sets whether to attempt to authenticate preemptively against proxy servers using basic
-     * authentication, and returns the updated ClientConfiguration object so that additional method
-     * calls may be chained together.
-     *
-     * @param preemptiveBasicProxyAuth
-     *            Whether to authenticate preemptively against proxy server.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withPreemptiveBasicProxyAuth(boolean preemptiveBasicProxyAuth) {
-        setPreemptiveBasicProxyAuth(preemptiveBasicProxyAuth);
-        return this;
-    }
-
-    /**
-     * Returns the expiration time (in milliseconds) for a connection in the connection pool. When
-     * retrieving a connection from the pool to make a request, the total time that the connection
-     * has been open is compared against this value. Connections which have been open for longer are
-     * discarded, and if needed a new connection is created.
-     * <p>
-     * Tuning this setting down (together with an appropriately-low setting for Java's DNS cache
-     * TTL) ensures that your application will quickly rotate over to new IP addresses when the
-     * service begins announcing them through DNS, at the cost of having to re-establish new
-     * connections more frequently.
-     *
-     * @return the connection TTL, in milliseconds
-     */
-    public long getConnectionTTL() {
-        return connectionTTL;
-    }
-
-    /**
-     * Sets the expiration time (in milliseconds) for a connection in the connection pool. When
-     * retrieving a connection from the pool to make a request, the total time that the connection
-     * has been open is compared against this value. Connections which have been open for longer are
-     * discarded, and if needed a new connection is created.
-     * <p>
-     * Tuning this setting down (together with an appropriately-low setting for Java's DNS cache
-     * TTL) ensures that your application will quickly rotate over to new IP addresses when the
-     * service begins announcing them through DNS, at the cost of having to re-establish new
-     * connections more frequently.
-     * <p>
-     * By default, it is set to {@code -1], i.e. connections do not expire.
-     *
-     * @param connectionTTL
-     *            the connection TTL, in milliseconds
-     */
-    public void setConnectionTTL(long connectionTTL) {
-        this.connectionTTL = connectionTTL;
-    }
-
-    /**
-     * Sets the expiration time (in milliseconds) for a connection in the connection pool. When
-     * retrieving a connection from the pool to make a request, the total time that the connection
-     * has been open is compared against this value. Connections which have been open for longer are
-     * discarded, and if needed a new connection is created.
-     * <p>
-     * Tuning this setting down (together with an appropriately-low setting for Java's DNS cache
-     * TTL) ensures that your application will quickly rotate over to new IP addresses when the
-     * service begins announcing them through DNS, at the cost of having to re-establish new
-     * connections more frequently.
-     * <p>
-     * By default, it is set to {@code -1}, i.e. connections do not expire.
-     *
-     * @param connectionTTL
-     *            the connection TTL, in milliseconds
-     * @return the updated ClientConfiguration object
-     */
-    public ClientConfiguration withConnectionTTL(long connectionTTL) {
-        setConnectionTTL(connectionTTL);
-        return this;
-    }
-
-    /**
-     * Returns the maximum amount of time that an idle connection may sit in the connection pool and
-     * still be eligible for reuse. When retrieving a connection from the pool to make a request,
-     * the amount of time the connection has been idle is compared against this value. Connections
-     * which have been idle for longer are discarded, and if needed a new connection is created.
-     * <p>
-     * Tuning this setting down reduces the likelihood of a race condition (wherein you begin
-     * sending a request down a connection which appears to be healthy, but before it arrives the
-     * service decides the connection has been idle for too long and closes it) at the cost of
-     * having to re-establish new connections more frequently.
-     *
-     * @return the connection maximum idle time, in milliseconds
-     */
-    public long getConnectionMaxIdleMillis() {
-        return connectionMaxIdleMillis;
-    }
-
-    /**
-     * Sets the maximum amount of time that an idle connection may sit in the connection pool and
-     * still be eligible for reuse. When retrieving a connection from the pool to make a request,
-     * the amount of time the connection has been idle is compared against this value. Connections
-     * which have been idle for longer are discarded, and if needed a new connection is created.
-     * <p>
-     * Tuning this setting down reduces the likelihood of a race condition (wherein you begin
-     * sending a request down a connection which appears to be healthy, but before it arrives the
-     * service decides the connection has been idle for too long and closes it) at the cost of
-     * having to re-establish new connections more frequently.
-     * <p>
-     * By default, it is set to one minute (60000ms).
-     *
-     * @param connectionMaxIdleMillis
-     *            the connection maximum idle time, in milliseconds
-     */
-    public void setConnectionMaxIdleMillis(long connectionMaxIdleMillis) {
-        this.connectionMaxIdleMillis = connectionMaxIdleMillis;
-    }
-
-    /**
-     * Sets the maximum amount of time that an idle connection may sit in the connection pool and
-     * still be eligible for reuse. When retrieving a connection from the pool to make a request,
-     * the amount of time the connection has been idle is compared against this value. Connections
-     * which have been idle for longer are discarded, and if needed a new connection is created.
-     * <p>
-     * Tuning this setting down reduces the likelihood of a race condition (wherein you begin
-     * sending a request down a connection which appears to be healthy, but before it arrives the
-     * service decides the connection has been idle for too long and closes it) at the cost of
-     * having to re-establish new connections more frequently.
-     * <p>
-     * By default, it is set to one minute (60000ms).
-     *
-     * @param connectionMaxIdleMillis
-     *            the connection maximum idle time, in milliseconds
-     * @return the updated ClientConfiguration object
-     */
-    public ClientConfiguration withConnectionMaxIdleMillis(long connectionMaxIdleMillis) {
-
-        setConnectionMaxIdleMillis(connectionMaxIdleMillis);
-        return this;
-    }
-
-    /**
-     * Returns the amount of time (in milliseconds) that a connection can be idle in the connection pool before it must be
-     * validated to ensure it's still open. This "stale connection check" adds a small bit of overhead to validate the
-     * connection. Setting this value to larger values may increase the likelihood that the connection is not usable, potentially
-     * resulting in a {@link org.apache.http.NoHttpResponseException}. Lowering this setting increases the overhead when leasing
-     * connections from the connection pool. It is recommended to tune this setting based on how long a service allows a
-     * connection to be idle before closing.
-     *
-     * <p>A non positive value disables validation of connections.</p>
-     *
-     * <p>The default value is {@value #DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS} milliseconds.</p>
-     */
-    public int getValidateAfterInactivityMillis() {
-        return validateAfterInactivityMillis;
-    }
-
-    /**
-     * Sets the amount of time (in milliseconds) that a connection can be idle in the connection pool before it must be validated
-     * to ensure it's still open. This "stale connection check" adds a small bit of overhead to validate the connection. Setting
-     * this value to larger values may increase the likelihood that the connection is not usable, potentially resulting in a
-     * {@link org.apache.http.NoHttpResponseException}. Lowering this setting increases the overhead when leasing connections
-     * from the connection pool. It is recommended to tune this setting based on how long a service allows a connection to be
-     * idle before closing.
-     *
-     * <p>A non positive value disables validation of connections.</p>
-     *
-     * <p>The default value is {@value #DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS} milliseconds.</p>
-     *
-     * @param validateAfterInactivityMillis The allowed time, in milliseconds, a connection can be idle before it must be
-     *                                      re-validated.
-     */
-    public void setValidateAfterInactivityMillis(int validateAfterInactivityMillis) {
-        this.validateAfterInactivityMillis = validateAfterInactivityMillis;
-    }
-
-    /**
-     * Sets the amount of time (in milliseconds) that a connection can be idle in the connection pool before it must be validated
-     * to ensure it's still open. This "stale connection check" adds a small bit of overhead to validate the connection. Setting
-     * this value to larger values may increase the likelihood that the connection is not usable, potentially resulting in a
-     * {@link org.apache.http.NoHttpResponseException}. Lowering this setting increases the overhead when leasing connections
-     * from the connection pool. It is recommended to tune this setting based on how long a service allows a connection to be
-     * idle before closing.
-     *
-     * <p>A non positive value disables validation of connections.</p>
-     *
-     * <p>The default value is {@value #DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS} milliseconds.</p>
-     *
-     * @param validateAfterInactivityMillis The allowed time, in milliseconds, a connection can be idle before it must be
-     *                                      re-validated.
-     * @return The updated {@link ClientConfiguration} object.
-     */
-    public ClientConfiguration withValidateAfterInactivityMillis(int validateAfterInactivityMillis) {
-        setValidateAfterInactivityMillis(validateAfterInactivityMillis);
-        return this;
-    }
-
-    /**
-     * Returns whether or not TCP KeepAlive support is enabled.
-     */
-    public boolean useTcpKeepAlive() {
-        return tcpKeepAlive;
-    }
-
-    /**
-     * Sets whether or not to enable TCP KeepAlive support at the socket level.
-     */
-    public void setUseTcpKeepAlive(final boolean use) {
-        this.tcpKeepAlive = use;
-    }
-
-    /**
-     * Sets whether or not to enable TCP KeepAlive support at the socket level.
-     *
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withTcpKeepAlive(final boolean use) {
-        setUseTcpKeepAlive(use);
-        return this;
-    }
-
-    /**
-     * Returns the DnsResolver for resolving AWS IP addresses.
-     * Returns the {@link SystemDefaultDnsResolver} by default if not
-     * explicitly configured by the user.
-     */
-    public DnsResolver getDnsResolver() {
-        return dnsResolver;
-    }
-
-    /**
-     * Sets the DNS Resolver that should be used to for resolving AWS IP addresses.
-     */
-    public void setDnsResolver(final DnsResolver resolver) {
-        if (resolver == null) {
-            throw new IllegalArgumentException("resolver cannot be null");
-        }
-        this.dnsResolver = resolver;
-    }
-
-    /**
-     * Sets the DNS Resolver that should be used to for resolving AWS IP addresses.
-     *
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withDnsResolver(final DnsResolver resolver) {
-        setDnsResolver(resolver);
-        return this;
-    }
-
-    /**
-     * Returns whether or not to cache response metadata.
-     * <p>
-     * Response metadata is typically used for troubleshooting issues with AWS support staff when
-     * services aren't acting as expected.
-     * </p>
-     * <p>
-     * While this feature is useful for debugging it adds overhead and disabling it may
-     * be desired in high throughput applications.
-     * </p>
-     *
-     * @return true if response metadata will be cached
-     */
-    public boolean getCacheResponseMetadata() { return cacheResponseMetadata; }
-
-    /**
-     * Sets whether or not to cache response metadata.
-     * <p>
-     * Response metadata is typically used for troubleshooting issues with AWS support staff when
-     * services aren't acting as expected.
-     * </p>
-     * <p>
-     * While this feature is useful for debugging it adds overhead and disabling it may
-     * be desired in high throughput applications.
-     * </p>
-     *
-     * @param shouldCache true if response metadata should be cached
-     */
-    public void setCacheResponseMetadata(boolean shouldCache) {
-        this.cacheResponseMetadata = shouldCache;
-    }
-
-    /**
-     * Sets whether or not to cache response metadata.
-     * <p>
-     * Response metadata is typically used for troubleshooting issues with AWS support staff when
-     * services aren't acting as expected.
-     * </p>
-     * <p>
-     * While this feature is useful for debugging it adds overhead and disabling it may
-     * be desired in high throughput applications.
-     * </p>
-     *
-     * @param shouldCache true if response metadata should be cached
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withCacheResponseMetadata(final boolean shouldCache) {
-        setCacheResponseMetadata(shouldCache);
-        return this;
-    }
-
-    /**
-     * Returns the response metadata cache size.
-     */
-    public int getResponseMetadataCacheSize() {
-        return responseMetadataCacheSize;
-    }
-
-    /**
-     * Sets the response metadata cache size. By default, it is set to
-     * {@value #DEFAULT_RESPONSE_METADATA_CACHE_SIZE}.
-     *
-     * @param responseMetadataCacheSize
-     *            maximum cache size.
-     */
-    public void setResponseMetadataCacheSize(int responseMetadataCacheSize) {
-        this.responseMetadataCacheSize = responseMetadataCacheSize;
-    }
-
-    /**
-     * Sets the response metadata cache size. By default, it is set to
-     * {@value #DEFAULT_RESPONSE_METADATA_CACHE_SIZE}.
-     *
-     * @param responseMetadataCacheSize
-     *            maximum cache size.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withResponseMetadataCacheSize(int responseMetadataCacheSize) {
-        setResponseMetadataCacheSize(responseMetadataCacheSize);
-        return this;
-    }
-
-    /**
-     * Returns a non-null object that can be used to specify Apache HTTP client specific custom
-     * configurations.
-     */
-    public ApacheHttpClientConfig getApacheHttpClientConfig() {
-        return apacheHttpClientConfig;
-    }
-
-    /**
-     * Returns the instance of {@link SecureRandom} configured by the user; or the JDK default if it
-     * is null.
-     *
-     * @return a non-null instance of SecureRandom.
-     */
-    public SecureRandom getSecureRandom() {
-        if (secureRandom == null)
-            secureRandom = new SecureRandom();
-        return secureRandom;
-    }
-
-    /**
-     * Sets an instance of {@link SecureRandom} to be used by the SDK.
-     */
-    public void setSecureRandom(SecureRandom secureRandom) {
-        this.secureRandom = secureRandom;
-    }
-
-    /**
-     * Fluent API for {@link #setSecureRandom(SecureRandom)}.
-     */
-    public ClientConfiguration withSecureRandom(SecureRandom secureRandom) {
-        setSecureRandom(secureRandom);
-        return this;
-    }
-
-    /**
-     * Returns the use expect continue flag
-     */
-    public boolean isUseExpectContinue() {
-        return useExpectContinue;
-    }
-
-    /**
-     * Sets if use expect continue should be enabled. By default, it is set to
-     * {@value #DEFAULT_USE_EXPECT_CONTINUE}.
-     *
-     * @param useExpectContinue
-     *            use expect continue HTTP/1.1 header.
-     */
-    public void setUseExpectContinue(boolean useExpectContinue) {
-        this.useExpectContinue = useExpectContinue;
-    }
-
-    /**
-     * Sets if use expect continue should be enabled. By default, it is set to
-     * {@value #DEFAULT_USE_EXPECT_CONTINUE}.
-     *
-     * @param useExpectContinue
-     *            use expect continue HTTP/1.1 header.
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withUseExpectContinue(boolean useExpectContinue) {
-        setUseExpectContinue(useExpectContinue);
-
-        return this;
-    }
-
-    /**
-     * Adds a header to be added on all requests and returns the {@link ClientConfiguration} object
-     *
-     * @param name
-     *            the name of the header
-     * @param value
-     *            the value of the header
-     *
-     * @return The updated ClientConfiguration object.
-     */
-    public ClientConfiguration withHeader(String name, String value) {
-        addHeader(name, value);
-        return this;
-    }
-
-    /**
-     * Adds a header to be added on all requests
-     *
-     * @param name
-     *            the name of the header
-     * @param value
-     *            the value of the header
-     */
-    public void addHeader(String name, String value) {
-        headers.put(name, value);
-    }
-
-    /**
-     * Returns headers to be added to all requests
-     *
-     * @return headers to be added to all requests
-     */
-    public Map<String, String> getHeaders() {
-        return Collections.unmodifiableMap(headers);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/DefaultRequest.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/DefaultRequest.java
--- ./src/main/java/com/amazonaws/DefaultRequest.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/DefaultRequest.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,365 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.event.ProgressInputStream;
-import com.amazonaws.handlers.HandlerContextKey;
-import com.amazonaws.http.HttpMethodName;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.json.Jackson;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Default implementation of the {@linkplain com.amazonaws.Request} interface.
- * <p>
- * This class is only intended for internal use inside the AWS client libraries.
- * Callers shouldn't ever interact directly with objects of this class.
- */
-@NotThreadSafe
-public class DefaultRequest<T> implements Request<T> {
-
-    /** The resource path being requested */
-    private String resourcePath;
-
-    /**
-     * Map of the parameters being sent as part of this request.
-     * <p>
-     * Note that a LinkedHashMap is used, since we want to preserve the
-     * insertion order so that members of a list parameter will still be ordered
-     * by their indices when they are marshalled into the query string.
-     *
-     * Lists values in this Map must use an implementation that allows
-     * null values to be present.
-     */
-    private Map<String, List<String>> parameters = new LinkedHashMap<String, List<String>>();
-
-    /** Map of the headers included in this request */
-    private Map<String, String> headers = new HashMap<String, String>();
-
-    /** The service endpoint to which this request should be sent */
-    private URI endpoint;
-
-    /** The name of the service to which this request is being sent */
-    private String serviceName;
-
-    /**
-     * The original, user facing request object which this internal request
-     * object is representing
-     */
-    private final AmazonWebServiceRequest originalRequest;
-
-    /** The HTTP method to use when sending this request. */
-    private HttpMethodName httpMethod = HttpMethodName.POST;
-
-    /** An optional stream from which to read the request payload. */
-    private InputStream content;
-
-    /** An optional time offset to account for clock skew */
-    private int timeOffset;
-
-    /** All AWS Request metrics are collected into this object. */
-    private AWSRequestMetrics metrics;
-
-    /**
-     * Context associated with a request. Mainly used to transfer
-     * information between different {@link com.amazonaws.handlers.RequestHandler2}
-     */
-    private final Map<HandlerContextKey<?>, Object> handlerContext = new
-            HashMap<HandlerContextKey<?>, Object>();
-
-    /**
-     * Constructs a new DefaultRequest with the specified service name and the
-     * original, user facing request object.
-     *
-     * @param serviceName
-     *            The name of the service to which this request is being sent.
-     * @param originalRequest
-     *            The original, user facing, AWS request being represented by
-     *            this internal request object.
-     */
-    public DefaultRequest(AmazonWebServiceRequest originalRequest, String serviceName) {
-        this.serviceName = serviceName;
-
-        this.originalRequest = originalRequest == null ? AmazonWebServiceRequest.NOOP
-                                                       : originalRequest;
-        this.handlerContext.putAll(this.originalRequest.getHandlerContext());
-    }
-
-    /**
-     * Constructs a new DefaultRequest with the specified service name and no
-     * specified original, user facing request object.
-     *
-     * @param serviceName
-     *            The name of the service to which this request is being sent.
-     */
-    public DefaultRequest(String serviceName) {
-        this(null, serviceName);
-    }
-
-
-    /**
-     * Returns the original, user facing request object which this internal
-     * request object is representing.
-     *
-     * @return The original, user facing request object which this request
-     *         object is representing.
-     */
-    public AmazonWebServiceRequest getOriginalRequest() {
-        return originalRequest;
-    }
-
-    /**
-     * @see com.amazonaws.Request#addHeader(java.lang.String, java.lang.String)
-     */
-    public void addHeader(String name, String value) {
-        headers.put(name, value);
-    }
-
-    /**
-     * @see com.amazonaws.Request#getHeaders()
-     */
-    public Map<String, String> getHeaders() {
-        return headers;
-    }
-
-    /**
-     * @see com.amazonaws.Request#setResourcePath(java.lang.String)
-     */
-    public void setResourcePath(String resourcePath) {
-        this.resourcePath = resourcePath;
-    }
-
-    /**
-     * @see com.amazonaws.Request#getResourcePath()
-     */
-    public String getResourcePath() {
-        return resourcePath;
-    }
-
-    /**
-     * @see com.amazonaws.Request#addParameter(java.lang.String, java.lang.String)
-     */
-    public void addParameter(String name, String value) {
-        List<String> paramList = parameters.get(name);
-        if (paramList == null) {
-            paramList = new ArrayList<String>();
-            parameters.put(name, paramList);
-        }
-        paramList.add(value);
-    }
-
-    /**
-     *
-     * @see com.amazonaws.Request#addParameters(java.lang.String, java.util.List)
-     */
-    public void addParameters(String name, List<String> values) {
-        if (values == null) return;
-        for (String value : values) {
-            addParameter(name, value);
-        }
-    }
-
-    /**
-     * @see com.amazonaws.Request#getParameters()
-     */
-    public Map<String, List<String>> getParameters() {
-        return parameters;
-    }
-
-    /**
-     * @see com.amazonaws.Request#withParameter(java.lang.String, java.lang.String)
-     */
-    public Request<T> withParameter(String name, String value) {
-        addParameter(name, value);
-        return this;
-    }
-
-    /**
-     * @see com.amazonaws.Request#getHttpMethod()
-     */
-    public HttpMethodName getHttpMethod() {
-        return httpMethod;
-    }
-
-    /**
-     * @see com.amazonaws.Request#setHttpMethod(com.amazonaws.http.HttpMethodName)
-     */
-    public void setHttpMethod(HttpMethodName httpMethod) {
-        this.httpMethod = httpMethod;
-    }
-
-    /**
-     * @see com.amazonaws.Request#setEndpoint(java.net.URI)
-     */
-    public void setEndpoint(URI endpoint) {
-        this.endpoint = endpoint;
-    }
-
-    /**
-     * @see com.amazonaws.Request#getEndpoint()
-     */
-    public URI getEndpoint() {
-        return endpoint;
-    }
-
-    /**
-     * @see com.amazonaws.Request#getServiceName()
-     */
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    /**
-     * @see com.amazonaws.Request#getContent()
-     */
-    public InputStream getContent() {
-        return content;
-    }
-
-    /**
-     * @see com.amazonaws.Request#setContent(java.io.InputStream)
-     */
-    public void setContent(InputStream content) {
-        this.content = content;
-    }
-
-    /**
-     * @see com.amazonaws.Request#setHeaders(java.util.Map)
-     */
-    public void setHeaders(Map<String, String> headers) {
-        this.headers.clear();
-        this.headers.putAll(headers);
-    }
-
-    /**
-     * @see com.amazonaws.Request#setParameters(java.util.Map)
-     */
-    public void setParameters(Map<String, List<String>> parameters) {
-        this.parameters.clear();
-        this.parameters.putAll(parameters);
-    }
-
-    /**
-     * @see com.amazonaws.Request#getTimeOffset
-     */
-    public int getTimeOffset() {
-        return timeOffset;
-    }
-
-    /**
-     * @see Request#setTimeOffset(int)
-     */
-    public void setTimeOffset(int timeOffset) {
-        this.timeOffset = timeOffset;
-    }
-
-    /**
-     * @see Request#setTimeOffset(int)
-     */
-    public Request<T> withTimeOffset(int timeOffset) {
-        setTimeOffset(timeOffset);
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append(getHttpMethod()).append(" ");
-        builder.append(getEndpoint()).append(" ");
-        String resourcePath = getResourcePath();
-
-        if (resourcePath == null) {
-            builder.append("/");
-        }
-        else {
-            if (!resourcePath.startsWith("/")) {
-                builder.append("/");
-            }
-            builder.append(resourcePath);
-        }
-        builder.append(" ");
-        if (!getParameters().isEmpty()) {
-            builder.append("Parameters: (")
-                   .append(Jackson.toJsonString(parameters));
-        }
-
-        if (!getHeaders().isEmpty()) {
-            builder.append("Headers: (");
-            for (String key : getHeaders().keySet()) {
-                String value = getHeaders().get(key);
-                builder.append(key).append(": ").append(value).append(", ");
-            }
-            builder.append(") ");
-        }
-
-        return builder.toString();
-    }
-
-    @Override
-    public AWSRequestMetrics getAWSRequestMetrics() {
-        return metrics;
-    }
-
-    @Override
-    public void setAWSRequestMetrics(AWSRequestMetrics metrics) {
-        if (this.metrics == null) {
-            this.metrics = metrics;
-        } else {
-            throw new IllegalStateException("AWSRequestMetrics has already been set on this request");
-        }
-    }
-
-    @Override
-    public <X> void addHandlerContext(HandlerContextKey<X> key, X value) {
-        handlerContext.put(key, value);
-    }
-
-    @Override
-    public <X> X getHandlerContext(HandlerContextKey<X> key) {
-        return (X) handlerContext.get(key);
-    }
-
-    @SuppressWarnings("resource")
-    @Override
-    public InputStream getContentUnwrapped() {
-        InputStream is = getContent();
-        if (is == null)
-            return null;
-        // We want to disable the progress reporting when the stream is
-        // consumed for signing purpose.
-        while (is instanceof ProgressInputStream) {
-            ProgressInputStream pris = (ProgressInputStream)is;
-            is = pris.getWrappedInputStream();
-        }
-        return is;
-    }
-
-    @Override
-    public ReadLimitInfo getReadLimitInfo() {
-        return originalRequest;
-    }
-
-    @Override
-    public Object getOriginalRequestObject() {
-        return originalRequest;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/DnsResolver.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/DnsResolver.java
--- ./src/main/java/com/amazonaws/DnsResolver.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/DnsResolver.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Given a hostname, will resolve the hostname to an ip, or list of ip addresses.
- */
-public interface DnsResolver {
-    InetAddress[] resolve(String host) throws UnknownHostException;
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/DeliveryMode.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/DeliveryMode.java
--- ./src/main/java/com/amazonaws/event/DeliveryMode.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/DeliveryMode.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,45 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-/**
- * Used to indicate whether it is safe to deliver progress events to the
- * listener synchronously. In general, a progress listener should never block,
- * which is a necessary condition for the safety for synchronous delivery.
- * 
- * @see SyncProgressListener
- */
-public interface DeliveryMode {
-    /**
-     * Returns true if it is safe to make a synchronous callback to the
-     * implementing listener without the risk of incurring undue latency; false
-     * otherwise.
-     */
-    public boolean isSyncCallSafe();
-
-    /**
-     * Provides convenient method to check if a listener is safe to be invoked
-     * synchronously.
-     */
-    public static class Check {
-        public static boolean isSyncCallSafe(ProgressListener listener) {
-            if (listener instanceof DeliveryMode) {
-                DeliveryMode mode = (DeliveryMode) listener;
-                return mode.isSyncCallSafe();
-            }
-            return listener == null;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressEventFilter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressEventFilter.java
--- ./src/main/java/com/amazonaws/event/ProgressEventFilter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressEventFilter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-/**
- * An interface that filters the incoming events before passing
- * them into the registered listeners.
- */
-public interface ProgressEventFilter {
-
-    /**
-     * Returns the filtered event object that will be actually passed into
-     * the listeners. Returns null if the event should be completely blocked.
-     */
-    public ProgressEvent filter(ProgressEvent progressEvent);
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressEvent.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressEvent.java
--- ./src/main/java/com/amazonaws/event/ProgressEvent.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressEvent.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,180 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import com.amazonaws.annotation.Immutable;
-
-import java.util.EnumMap;
-import java.util.Map;
-
-/**
- * A progress event. Typically this is used to notify a chunk of bytes has been
- * transferred. Also used to notify other types of progress events such as a
- * transfer starting, or failing.
- * <p>
- * The legacy Amazon S3 progress event
- * com.amazonaws.services.s3.model.ProgressEvent has been deprecated in favor of
- * this new class.
- * </p>
- */
-@Immutable
-public class ProgressEvent {
-    /** The number of bytes associated with the progress event. */
-    private final long bytes;
-    private final ProgressEventType eventType;
-
-    /**
-     * Creates a BYTE_TRANSFER_EVENT with the specified bytesTransferred data.
-     */
-    @Deprecated
-    public ProgressEvent(long bytes) {
-        this(ProgressEventType.BYTE_TRANSFER_EVENT, bytes);
-    }
-
-    /**
-     * Creates a ProgressEvent object with the specified event type.
-     *
-     * @param eventType
-     *            Type of the progress event. This parameter must not be null.
-     */
-    public ProgressEvent(ProgressEventType eventType) {
-        this(eventType, 0);
-    }
-
-    /**
-     * Creates a ProgressEvent object.
-     *
-     * @param eventType
-     *            Type of the progress event. This parameter must not be null.
-     * @param bytes
-     *            Number of bytes involved.
-     */
-    public ProgressEvent(ProgressEventType eventType, long bytes) {
-        if (eventType == null)
-            throw new IllegalArgumentException("eventType must not be null.");
-        if (bytes < 0)
-            throw new IllegalArgumentException("bytes reported must be non-negative");
-        this.eventType = eventType;
-        this.bytes = bytes;
-    }
-
-    /**
-     * Returns the number of bytes associated with the event. The number of
-     * bytes are not necessarily the same as the number of bytes transferred,
-     * and it's meaning depends on the specific event type. For example, the
-     * bytes of a {@link ProgressEventType#REQUEST_CONTENT_LENGTH_EVENT} refers
-     * to the expected number of bytes to be sent to AWS, not the actual number
-     * of bytes that have been transferred.
-     */
-    public long getBytes() {
-        return bytes;
-    }
-
-    /**
-     * Convenient method to returns the number of bytes transferred in this
-     * event, or the number of bytes reset (or discarded) if negative. In
-     * particular, bytes of a content-length event is excluded.
-     */
-    public long getBytesTransferred() {
-        switch(eventType) {
-            case REQUEST_BYTE_TRANSFER_EVENT:
-            case RESPONSE_BYTE_TRANSFER_EVENT:
-                return bytes;
-            case HTTP_RESPONSE_CONTENT_RESET_EVENT:
-            case HTTP_REQUEST_CONTENT_RESET_EVENT:
-            case RESPONSE_BYTE_DISCARD_EVENT:
-                return 0 - bytes;
-        default:
-            return 0;
-        }
-    }
-
-    /**
-     * Returns the unique event code identifying the type of event this object
-     * represents.
-     *
-     * @return The unique event code that identifies what type of specific type
-     *         of event this object represents.
-     *
-     * @deprecated Use {@link #getEventType()} instead.
-     */
-    @Deprecated
-    public int getEventCode() {
-        Integer legacyCode =  legacyEventCodes.get(eventType);
-        // Returns -1 if the event type does not have a legacy event code
-        return legacyCode == null ? -1 : legacyCode;
-    }
-
-    /**
-     * Returns the type of event this object represents. This method never
-     * returns null.
-     *
-     * @return The type of event this object represents.
-     */
-    public ProgressEventType getEventType() {
-        return eventType;
-    }
-
-    // Deprecated integer event codes
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_PREPARING_EVENT} */
-    @Deprecated public static final int PREPARING_EVENT_CODE = 1;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_STARTED_EVENT} */
-    @Deprecated public static final int STARTED_EVENT_CODE = 2;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_COMPLETED_EVENT} */
-    @Deprecated public static final int COMPLETED_EVENT_CODE = 4;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_FAILED_EVENT} */
-    @Deprecated public static final int FAILED_EVENT_CODE = 8;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_CANCELED_EVENT} */
-    @Deprecated public static final int CANCELED_EVENT_CODE = 16;
-
-    /** @deprecated Replaced by {@link ProgressEventType#HTTP_REQUEST_CONTENT_RESET_EVENT} */
-    @Deprecated public static final int RESET_EVENT_CODE = 32;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_PART_STARTED_EVENT} */
-    @Deprecated public static final int PART_STARTED_EVENT_CODE = 1024;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_PART_COMPLETED_EVENT} */
-    @Deprecated public static final int PART_COMPLETED_EVENT_CODE = 2048;
-
-    /** @deprecated Replaced by {@link ProgressEventType#TRANSFER_PART_FAILED_EVENT} */
-    @Deprecated public static final int PART_FAILED_EVENT_CODE = 4096;
-
-    // Mapping from event types to the legacy event codes
-    private static final Map<ProgressEventType, Integer> legacyEventCodes =
-        new EnumMap<ProgressEventType, Integer>(ProgressEventType.class);
-    static {
-        legacyEventCodes.put(ProgressEventType.BYTE_TRANSFER_EVENT,              0);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_PREPARING_EVENT,         PREPARING_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_STARTED_EVENT,           STARTED_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_COMPLETED_EVENT,         COMPLETED_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_FAILED_EVENT,            FAILED_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_CANCELED_EVENT,          CANCELED_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.HTTP_REQUEST_CONTENT_RESET_EVENT, RESET_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.HTTP_RESPONSE_CONTENT_RESET_EVENT,RESET_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_PART_STARTED_EVENT,      PART_STARTED_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_PART_COMPLETED_EVENT,    PART_COMPLETED_EVENT_CODE);
-        legacyEventCodes.put(ProgressEventType.TRANSFER_PART_FAILED_EVENT,       PART_FAILED_EVENT_CODE);
-    }
-    
-    @Override
-    public String toString() {
-        return eventType + ", bytes: " + bytes;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressEventType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressEventType.java
--- ./src/main/java/com/amazonaws/event/ProgressEventType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressEventType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,184 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-/**
- * An enumeration that denotes various types of progress event.
- */
-public enum ProgressEventType {
-    //////////////////////////////////////////////////////////////////////////
-    // Request Cycle Event:
-    // related to the execution of a single http request-response to AWS
-    //////////////////////////////////////////////////////////////////////////
-    /**
-     * A general byte transfer event that happens during sending a request or
-     * reading a response.
-     */
-    @Deprecated
-    BYTE_TRANSFER_EVENT,
-    /**
-     * Event of the content length to be sent in a request.
-     */
-    REQUEST_CONTENT_LENGTH_EVENT,
-    /**
-     * Event of the content length received in a response.
-     */
-    RESPONSE_CONTENT_LENGTH_EVENT,
-
-    /**
-     * Used to indicate the number of bytes to be sent to AWS.
-     */
-    REQUEST_BYTE_TRANSFER_EVENT,
-    /**
-     * Used to indicate the number of bytes received from AWS.
-     */
-    RESPONSE_BYTE_TRANSFER_EVENT,
-    /**
-     * Used to indicate the number of bytes discarded after being received from AWS.
-     */
-    RESPONSE_BYTE_DISCARD_EVENT,
-
-    /* Generic request progress events */
-
-    /**
-     * Event indicating that the client has started sending the AWS API request.
-     * This type of event is guaranteed to be only fired once during a
-     * request-response cycle, even when the request is retried.
-     */
-    CLIENT_REQUEST_STARTED_EVENT,
-
-    /**
-     * Event indicating that the client has started sending the HTTP request.
-     * The request progress listener will be notified of multiple instances of
-     * this type of event if the request gets retried.
-     */
-    HTTP_REQUEST_STARTED_EVENT,
-
-    /**
-     * Event indicating that the client has finished sending the HTTP request.
-     * The request progress listener will be notified of multiple instances of
-     * this type of event if the request gets retried.
-     */
-    HTTP_REQUEST_COMPLETED_EVENT,
-
-    /**
-     * Event indicating that the HTTP request content is reset, which may or may not
-     * be caused by the retry of the request.
-     */
-    HTTP_REQUEST_CONTENT_RESET_EVENT,
-
-    /**
-     * Event indicating that a failed request is detected as retryable and is
-     * ready for the next retry.
-     */
-    CLIENT_REQUEST_RETRY_EVENT,
-
-    /**
-     * Event indicating that the client has started reading the HTTP response.
-     * The request progress listener will be notified of this event only if the
-     * client receives a successful service response (i.e. 2XX status code).
-     */
-    HTTP_RESPONSE_STARTED_EVENT,
-
-    /**
-     * Event indicating that the client has finished reading the HTTP response.
-     * The request progress listener will be notified of this event only if the
-     * client receives a successful service response (i.e. 2XX status code).
-     */
-    HTTP_RESPONSE_COMPLETED_EVENT,
-
-    /**
-     * Event indicating that the HTTP response content is reset.
-     */
-    HTTP_RESPONSE_CONTENT_RESET_EVENT,
-
-    /**
-     * Event indicating that the client has received a successful service
-     * response and has finished parsing the response data.
-     */
-    CLIENT_REQUEST_SUCCESS_EVENT,
-
-    /**
-     * Event indicating that a client request has failed (after retries have
-     * been conducted).
-     */
-    CLIENT_REQUEST_FAILED_EVENT,
-
-    //////////////////////////////////////////////////////////////////////////
-    // Transfer Event:
-    // Progress events that are used by S3 and Glacier client */
-    //////////////////////////////////////////////////////////////////////////
-    TRANSFER_PREPARING_EVENT,
-    TRANSFER_STARTED_EVENT,
-    TRANSFER_COMPLETED_EVENT,
-    TRANSFER_FAILED_EVENT,
-    TRANSFER_CANCELED_EVENT,
-    TRANSFER_PART_STARTED_EVENT,
-    TRANSFER_PART_COMPLETED_EVENT,
-    TRANSFER_PART_FAILED_EVENT;
-
-    /**
-     * Returns true if this event type is a transfer event, which may involve
-     * multiple request cycle events.
-     * 
-     * @see #isRequestCycleEvent()
-     */
-    public boolean isTransferEvent() {
-        switch (this) {
-            case TRANSFER_CANCELED_EVENT:
-            case TRANSFER_COMPLETED_EVENT:
-            case TRANSFER_FAILED_EVENT:
-            case TRANSFER_PART_COMPLETED_EVENT:
-            case TRANSFER_PART_FAILED_EVENT:
-            case TRANSFER_PART_STARTED_EVENT:
-            case TRANSFER_PREPARING_EVENT:
-            case TRANSFER_STARTED_EVENT:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Returns true if this event type is related to the execution of a 
-     * single http request-response to AWS; false otherwise.
-     */
-    public boolean isRequestCycleEvent() {
-        return !isTransferEvent();
-    }
-
-    /**
-     * Returns true if this even type is associated with some number of bytes;
-     * false otherwise.
-     */
-    public boolean isByteCountEvent() {
-        switch (this) {
-            case BYTE_TRANSFER_EVENT:
-            case HTTP_REQUEST_CONTENT_RESET_EVENT:
-            case HTTP_RESPONSE_CONTENT_RESET_EVENT:
-
-            case REQUEST_BYTE_TRANSFER_EVENT:
-            case RESPONSE_BYTE_TRANSFER_EVENT:
-
-            case RESPONSE_BYTE_DISCARD_EVENT:
-
-            case REQUEST_CONTENT_LENGTH_EVENT:
-            case RESPONSE_CONTENT_LENGTH_EVENT:
-                return true;
-            default:
-                return false;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressInputStream.java
--- ./src/main/java/com/amazonaws/event/ProgressInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,217 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.internal.SdkFilterInputStream;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Used for input stream progress tracking purposes.
- */
-@NotThreadSafe
-public abstract class ProgressInputStream extends SdkFilterInputStream {
-    /**
-     * Returns an input stream for request progress tracking purposes. If request/response progress
-     * tracking is not enabled, this method simply return the given input stream as is.
-     *
-     * @param is the request content input stream
-     * @deprecated
-     */
-    @Deprecated
-    public static InputStream inputStreamForRequest(InputStream is,
-            AmazonWebServiceRequest req) {
-        return req == null
-             ? is
-             : inputStreamForRequest(is, req.getGeneralProgressListener());
-    }
-
-    /**
-     * @param is               the request content input stream
-     * @param progressListener Optional progress listener
-     * @return If the progress listener is non null returns a new input stream decorated with
-     * progress reporting functionality. If progress listener is null it returns the same input
-     * stream.
-     */
-    @SdkInternalApi
-    public static InputStream inputStreamForRequest(InputStream is, ProgressListener progressListener) {
-        return progressListener == null
-                ? is
-                : new RequestProgressInputStream(is, progressListener);
-    }
-
-    /**
-     * Returns an input stream for response progress tracking purposes. If
-     * request/response progress tracking is not enabled, this method simply
-     * return the given input stream as is.
-     * 
-     * @param is the response content input stream
-     */
-    public static InputStream inputStreamForResponse(InputStream is, AmazonWebServiceRequest req) {
-        return req == null
-             ? is
-             : new ResponseProgressInputStream(is, req.getGeneralProgressListener());
-    }
-
-    /**
-     * Returns an input stream for response progress tracking purposes. If request/response progress tracking is not enabled, this
-     * method simply return the given input stream as is.
-     *
-     * @param is               the response content input stream
-     * @param progressListener Optional progress listener
-     * @return If the progress listener is non null returns a new input stream decorated with progress reporting functionality. If
-     * progress listener is null it returns the same input stream.
-     */
-    public static InputStream inputStreamForResponse(InputStream is, ProgressListener progressListener) {
-        return progressListener == null
-                ? is
-                : new ResponseProgressInputStream(is, progressListener);
-    }
-
-    /** The threshold of bytes between notifications. */
-    private static final int DEFAULT_NOTIFICATION_THRESHOLD = 8 * 1024;
-
-    private final ProgressListener listener;
-    private final int notifyThresHold;
-    /** The number of bytes read that the listener hasn't been notified about yet. */
-    private int unnotifiedByteCount;
-    private boolean hasBeenRead;
-    private boolean doneEOF;
-    private long notifiedByteCount;
-
-    public ProgressInputStream(InputStream is, ProgressListener listener) {
-        this(is, listener, DEFAULT_NOTIFICATION_THRESHOLD);
-    }
-
-    public ProgressInputStream(InputStream is, ProgressListener listener, int notifyThresHold) {
-        super(is);
-        if (is == null || listener == null)
-            throw new IllegalArgumentException();
-        this.notifyThresHold = notifyThresHold;
-        this.listener = listener;
-    }
-
-    /**
-     * The read method is called for the very first time.
-     * Defaults to do nothing.
-     */
-    protected void onFirstRead() {}
-    /**
-     * An end-of-file event is to be notified.
-     * Defaults to do nothing.
-     */
-    protected void onEOF() {}
-
-    /**
-     * Defaults to behave the same as {@link #onEOF()}.
-     */
-    protected void onClose() {
-        eof();
-    }
-    /**
-     * A reset event is to be notified.  Default to do nothing.
-     */
-    protected void onReset() {}
-    /**
-     * Upon notification of the number of bytes transferred since last
-     * notification.  Default to do nothing.
-     */
-    protected void onNotifyBytesRead() {}
-
-    /**
-     * Upon reading the given number of bytes.
-     * The default behavior is to accumulate the byte count and only fire off
-     * a notification by invoking {@link #onNotifyBytesRead()} if the count
-     * has exceeded the threshold.
-     */
-    private void onBytesRead(int bytesRead) {
-        unnotifiedByteCount += bytesRead;
-        if (unnotifiedByteCount >= notifyThresHold) {
-            onNotifyBytesRead();
-            notifiedByteCount += unnotifiedByteCount;
-            unnotifiedByteCount = 0;
-        }
-    }
-
-    @Override
-    public int read() throws IOException {
-        if (!hasBeenRead) {
-            onFirstRead();
-            hasBeenRead = true;
-        }
-        int ch = super.read();
-        if (ch == -1)
-            eof();
-        else
-            onBytesRead(1);
-        return ch;
-    }
-
-    @Override
-    public void reset() throws IOException {
-        super.reset();
-        onReset();
-        unnotifiedByteCount = 0;
-        notifiedByteCount = 0;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        if (!hasBeenRead) {
-            onFirstRead();
-            hasBeenRead = true;
-        }
-        int bytesRead = super.read(b, off, len);
-        if (bytesRead == -1)
-            eof();
-        else
-            onBytesRead(bytesRead);
-        return bytesRead;
-    }
-
-    private void eof() {
-        if (doneEOF)
-            return;
-        onEOF();
-        unnotifiedByteCount = 0;
-        doneEOF = true;
-    }
-
-    public final InputStream getWrappedInputStream() {
-        return in;
-    }
-
-    protected final int getUnnotifiedByteCount() {
-        return unnotifiedByteCount;
-    }
-
-    protected final long getNotifiedByteCount() {
-        return notifiedByteCount;
-    }
-
-    @Override
-    public void close() throws IOException {
-        onClose(); // report any left over bytes not yet reported
-        super.close();
-    }
-
-    public final ProgressListener getListener() {
-        return listener;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressListenerChain.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressListenerChain.java
--- ./src/main/java/com/amazonaws/event/ProgressListenerChain.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressListenerChain.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,106 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * An implementation of ProgressListener interface that delegates
- * progressChanged callback to multiple listeners. It also takes
- * an optional ProgressEventFilter to filter incoming events before
- * passing them to the listeners.
- * <p>
- * This class could be used for both Amazon S3 and Amazon Glacier clients. The
- * legacy Amazon S3 progress listener chain
- * com.amazonaws.services.s3.transfer.internal.ProgressListenerChain has been
- * deprecated in favor of this new class.
- * </p>
- */
-public class ProgressListenerChain implements ProgressListener, DeliveryMode {
-    private static final Log log = LogFactory.getLog(ProgressListenerChain.class);
-
-    private final List<ProgressListener> listeners = new CopyOnWriteArrayList<ProgressListener>();
-    private final ProgressEventFilter progressEventFilter;
-    /**
-     * True if synchronous callback to every listener in this chain is safe with
-     * no risk of incurring undue latency.
-     *
-     * @see SDKProgressPublisher
-     */
-    private volatile boolean syncCallSafe = true;
-
-    /**
-     * Create a listener chain that directly passes all the progress events to
-     * the specified listeners.
-     */
-    public ProgressListenerChain(ProgressListener... listeners) {
-        this(null, listeners);
-    }
-
-    /**
-     * Create a listener chain with a ProgressEventFilter.
-     */
-    public ProgressListenerChain(ProgressEventFilter progressEventFilter, ProgressListener... listeners) {
-        if (listeners == null) {
-            throw new IllegalArgumentException(
-                    "Progress Listeners cannot be null.");
-        }
-        for (ProgressListener listener : listeners)
-            addProgressListener(listener);
-        this.progressEventFilter = progressEventFilter;
-    }
-
-    public synchronized void addProgressListener(ProgressListener listener) {
-        if (listener == null) 
-            return;
-        if (syncCallSafe)
-            syncCallSafe = DeliveryMode.Check.isSyncCallSafe(listener);
-        this.listeners.add(listener);
-    }
-
-    public synchronized void removeProgressListener(ProgressListener listener) {
-        if (listener == null) return;
-        this.listeners.remove(listener);
-    }
-
-    /**
-     * Returns the listeners associated with this listener chain.
-     */
-    protected List<ProgressListener> getListeners() {
-        return listeners;
-    }
-
-    public void progressChanged(final ProgressEvent progressEvent) {
-        ProgressEvent filteredEvent = progressEvent;
-        if (progressEventFilter != null) {
-            filteredEvent = progressEventFilter.filter(progressEvent);
-            if (filteredEvent == null) return;
-        }
-
-        for ( ProgressListener listener : listeners ) {
-            try {
-                listener.progressChanged(filteredEvent);
-            } catch ( RuntimeException e ) {
-                log.warn("Couldn't update progress listener", e);
-            }
-        }
-    }
-
-    @Override public boolean isSyncCallSafe() { return syncCallSafe; }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressListener.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressListener.java
--- ./src/main/java/com/amazonaws/event/ProgressListener.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressListener.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,130 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import com.amazonaws.SdkClientException;
-
-/**
- * Listener interface for transfer progress events.
- * <p>
- * This class could be used for both Amazon S3 and Amazon Glacier clients. The
- * legacy Amazon S3 progress listener
- * com.amazonaws.services.s3.model.ProgressListener has been deprecated in favor
- * of this new class.
- * </p>
- *
- * @see ProgressEvent
- */
-public interface ProgressListener {
-	public static final ProgressListener NOOP = new NoOpProgressListener();
-
-    static class NoOpProgressListener implements ProgressListener, DeliveryMode {
-
-        @Override
-        public boolean isSyncCallSafe() {
-            return true;
-        }
-
-        @Override
-        public void progressChanged(ProgressEvent progressEvent) {
-        }
-    }
-
-    /**
-     * Called when progress has changed, such as additional bytes transferred,
-     * transfer failed, etc. The execution of the callback of this listener is managed
-     * by {@link SDKProgressPublisher}.  Implementation of this interface
-     * should never block.
-     * <p>
-     * If the implementation follows the best practice and doesn't block, it
-     * should then extends from {@link SyncProgressListener}.
-     * <p>
-     * Note any exception thrown by the listener will get ignored.
-     * Should there be need to capture any such exception, you may consider
-     * wrapping the listener with {@link ExceptionReporter#wrap(ProgressListener)}.
-     *
-     * @param progressEvent
-     *            The event describing the progress change.
-     *
-     * @see SDKProgressPublisher
-     * @see ExceptionReporter
-     */
-    public void progressChanged(ProgressEvent progressEvent);
-
-    /**
-     * A utility class for capturing and reporting the first exception thrown by
-     * a given progress listener. Note once an exception is thrown by the
-     * underlying listener, all subsequent events will no longer be notified to
-     * the listener.
-     */
-    public static class ExceptionReporter implements ProgressListener, DeliveryMode {
-        private final ProgressListener listener;
-        private final boolean syncCallSafe;
-        private volatile Throwable cause;
-
-        public ExceptionReporter(ProgressListener listener) {
-            if (listener == null)
-                throw new IllegalArgumentException();
-            this.listener = listener;
-            if (listener instanceof DeliveryMode) {
-                DeliveryMode cs = (DeliveryMode) listener;
-                syncCallSafe = cs.isSyncCallSafe();
-            } else
-                syncCallSafe = false;
-        }
-
-        /**
-         * Delivers the progress event to the underlying listener but only if
-         * there has not been an exception previously thrown by the listener.
-         * <p>
-         * {@inheritDoc}
-         */
-        @Override public void progressChanged(ProgressEvent progressEvent) {
-            if (cause != null)
-                return;
-            try {
-                this.listener.progressChanged(progressEvent);
-            } catch(Throwable t) {
-                cause = t;
-            }
-        }
-
-        /**
-         * Throws the underlying exception, if any, as an
-         * {@link SdkClientException}; or do nothing otherwise.
-         */
-        public void throwExceptionIfAny() {
-            if (cause != null)
-                throw new SdkClientException(cause);
-        }
-
-        /**
-         * Returns the underlying exception, if any; or null otherwise.
-         */
-        public Throwable getCause() {
-            return cause;
-        }
-
-        /**
-         * Returns a wrapper for the given listener to capture the first
-         * exception thrown.
-         */
-        public static ExceptionReporter wrap(ProgressListener listener) {
-            return new ExceptionReporter(listener);
-        }
-
-        @Override public boolean isSyncCallSafe() { return syncCallSafe; }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ProgressTracker.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressTracker.java
--- ./src/main/java/com/amazonaws/event/ProgressTracker.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ProgressTracker.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,61 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import com.amazonaws.event.request.Progress;
-import com.amazonaws.event.request.ProgressSupport;
-
-/**
- * Default implementation for progress tracking.
- */
-public class ProgressTracker extends SyncProgressListener {
-    public static final ProgressTracker NOOP = new ProgressTracker() {
-        @Override public void progressChanged(ProgressEvent progressEvent) {}
-    };
-
-    private final Progress progress = new ProgressSupport();
-
-    @Override
-    public void progressChanged(ProgressEvent progressEvent) {
-        long bytes = progressEvent.getBytes();
-        if (bytes <= 0)
-            return;
-        switch (progressEvent.getEventType()) {
-            case REQUEST_CONTENT_LENGTH_EVENT:
-                progress.addRequestContentLength(bytes);
-                break;
-            case RESPONSE_CONTENT_LENGTH_EVENT:
-                progress.addResponseContentLength(bytes);
-                break;
-            case REQUEST_BYTE_TRANSFER_EVENT:
-                progress.addRequestBytesTransferred(bytes);
-                break;
-            case RESPONSE_BYTE_TRANSFER_EVENT:
-                progress.addResponseBytesTransferred(bytes);
-                break;
-            case HTTP_REQUEST_CONTENT_RESET_EVENT:
-                progress.addRequestBytesTransferred(0-bytes);
-                break;
-            case HTTP_RESPONSE_CONTENT_RESET_EVENT: 
-            case RESPONSE_BYTE_DISCARD_EVENT: 
-                progress.addResponseBytesTransferred(0-bytes);
-                break;
-            default:
-                break;
-        }
-    }
-    
-    public Progress getProgress() { return progress; }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/request/Progress.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/request/Progress.java
--- ./src/main/java/com/amazonaws/event/request/Progress.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/request/Progress.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,64 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event.request;
-
-import com.amazonaws.annotation.ThreadSafe;
-
-/**
- * Base class used to represent the progress of a logical request/response,
- * which may correspond to either be a physical http request/response, or
- * multiple requests/responses as in a composite operation such as
- * multi-part uploads.
- * 
- * @see ProgressSupport
- */
-@ThreadSafe
-public class Progress {
-    public static final Progress NOOP = new Progress();
-    private static final String MSG = "No progress tracking configured";
-    protected Progress() {}
-
-    /**
-     * Returns true if progress tracking is enabled; false otherwise.
-     */
-    public boolean isEnabled() { return false; }
-    /**
-     * @param bytes can be negative if it was a reset event.
-     */
-    public void addRequestBytesTransferred(long bytes) {}
-    /**
-     * @param bytes can be negative if it was a reset event.
-     */
-    public void addResponseBytesTransferred(long bytes) {}
-
-    public long getRequestContentLength() { 
-        throw new UnsupportedOperationException(MSG);
-    }
-
-    public void addRequestContentLength(long contentLength) {}
-    public long getRequestBytesTransferred() { 
-        throw new UnsupportedOperationException(MSG);
-    }
-
-    public long getResponseContentLength() {
-        throw new UnsupportedOperationException(MSG);
-    }
-
-    public void addResponseContentLength(long contentLength) {}
-
-    public long getResponseBytesTransferred() {
-        throw new UnsupportedOperationException(MSG);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/event/request/ProgressSupport.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/request/ProgressSupport.java
--- ./src/main/java/com/amazonaws/event/request/ProgressSupport.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/request/ProgressSupport.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,124 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event.request;
-
-import com.amazonaws.annotation.ThreadSafe;
-
-/**
- * An actual implementation to represent the progress of a request/response.
- */
-@ThreadSafe
-public class ProgressSupport extends Progress {
-    /* Request transfer progress */
-    private volatile long requestContentLength = -1;
-    private volatile long requestBytesTransferred;
-
-    /* Response transfer progress */
-    private volatile long responseContentLength = -1;
-    private volatile long responseBytesTransferred;
-
-    private static final Object lock = new Object();
-
-    /**
-     * Returns the number of bytes to be expected in the request, or -1 if the
-     * number is unknown (e.g. when the request is still not serialized yet, or
-     * when the request contains raw InputStream as the payload in which case
-     * the SDK cannot infer the content-length in advance).
-     */
-    @Override
-    public long getRequestContentLength() {
-        return requestContentLength;
-    }
-
-    /**
-     * Adds the number of bytes to be expected in the request.
-     */
-    @Override
-    public void addRequestContentLength(long contentLength) {
-        if (contentLength < 0)
-            throw new IllegalArgumentException();
-        synchronized(lock) {
-            if (this.requestContentLength == -1)
-                this.requestContentLength = contentLength;
-            else
-                this.requestContentLength += contentLength;
-        }
-    }
-
-    /**
-     * Returns the number of bytes that have been transferred in the request.
-     */
-    @Override
-    public long getRequestBytesTransferred() {
-        return requestBytesTransferred;
-    }
-
-    /**
-     * Returns the number of bytes to be expected in the response, or -1 if the
-     * number is unknown (e.g. when the client hasn't received the response
-     * yet).
-     */
-    @Override
-    public long getResponseContentLength() {
-        return responseContentLength;
-    }
-
-    /**
-     * Adds the number of bytes to be expected in the response.
-     */
-    @Override
-    public void addResponseContentLength(long contentLength) {
-        if (contentLength < 0)
-            throw new IllegalArgumentException();
-        synchronized(lock) {
-            if (this.responseContentLength == -1)
-                this.responseContentLength = contentLength;
-            else
-                this.responseContentLength += contentLength;
-        }
-    }
-
-    /**
-     * Returns the number of bytes that have been transferred in the response.
-     */
-    @Override
-    public long getResponseBytesTransferred() {
-        return responseBytesTransferred;
-    }
-
-    @Override
-    public void addRequestBytesTransferred(long bytes) {
-        synchronized (lock) {
-            requestBytesTransferred += bytes;
-        }
-    }
-
-    @Override
-    public void addResponseBytesTransferred(long bytes) {
-        synchronized(lock) {
-            responseBytesTransferred += bytes;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return String.format("Request: %d/%d, Response: %d/%d",
-                requestBytesTransferred, requestContentLength,
-                responseBytesTransferred, responseContentLength);
-    }
-
-    @Override
-    public final boolean isEnabled() { return true; }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/event/RequestProgressInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/RequestProgressInputStream.java
--- ./src/main/java/com/amazonaws/event/RequestProgressInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/RequestProgressInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,45 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import static com.amazonaws.event.SDKProgressPublisher.publishRequestBytesTransferred;
-import static com.amazonaws.event.SDKProgressPublisher.publishRequestReset;
-
-import java.io.InputStream;
-
-/**
- * Used for request input stream progress tracking purposes.
- */
-class RequestProgressInputStream extends ProgressInputStream {
-
-    RequestProgressInputStream(InputStream is, ProgressListener listener) {
-        super(is, listener);
-    }
-
-    @Override
-    protected void onReset() {
-        publishRequestReset(getListener(), getNotifiedByteCount());
-    }
-
-    @Override
-    protected void onEOF() {
-        onNotifyBytesRead();
-    }
-
-    @Override
-    protected void onNotifyBytesRead() {
-        publishRequestBytesTransferred(getListener(), getUnnotifiedByteCount());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/ResponseProgressInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ResponseProgressInputStream.java
--- ./src/main/java/com/amazonaws/event/ResponseProgressInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/ResponseProgressInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-import static com.amazonaws.event.SDKProgressPublisher.publishResponseBytesTransferred;
-import static com.amazonaws.event.SDKProgressPublisher.publishResponseReset;
-
-import java.io.InputStream;
-
-/**
- * Used for response input stream progress tracking purposes.
- */
-class ResponseProgressInputStream extends ProgressInputStream {
-    ResponseProgressInputStream(InputStream is, ProgressListener listener) {
-        super(is, listener);
-    }
-
-    @Override
-    protected void onReset() {
-        publishResponseReset(getListener(), getNotifiedByteCount());
-    }
-
-    @Override
-    protected void onEOF() {
-        onNotifyBytesRead();
-    }
-
-    @Override
-    protected void onNotifyBytesRead() {
-        publishResponseBytesTransferred(getListener(), getUnnotifiedByteCount());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/SDKProgressPublisher.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/SDKProgressPublisher.java
--- ./src/main/java/com/amazonaws/event/SDKProgressPublisher.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/SDKProgressPublisher.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,280 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-import static com.amazonaws.event.ProgressEventType.HTTP_REQUEST_CONTENT_RESET_EVENT;
-import static com.amazonaws.event.ProgressEventType.HTTP_RESPONSE_CONTENT_RESET_EVENT;
-import static com.amazonaws.event.ProgressEventType.REQUEST_BYTE_TRANSFER_EVENT;
-import static com.amazonaws.event.ProgressEventType.REQUEST_CONTENT_LENGTH_EVENT;
-import static com.amazonaws.event.ProgressEventType.RESPONSE_BYTE_TRANSFER_EVENT;
-import static com.amazonaws.event.ProgressEventType.RESPONSE_CONTENT_LENGTH_EVENT;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-
-import org.apache.commons.logging.LogFactory;
-
-/**
- * This class is responsible for executing the callback method of
- * ProgressListener; listener callbacks are executed sequentially in a separate
- * single thread.
- */
-public class SDKProgressPublisher {
-
-    /**
-     * Used for testing purposes only.
-     */
-    private static volatile Future<?> latestFutureTask;
-
-    /**
-     * Used to deliver a progress event to the given listener.
-     *
-     * @return the future of a submitted task; or null if the delivery is
-     * synchronous with no future task involved.  Note a listener should never
-     * block, and therefore returning null is the typical case.
-     */
-    public static Future<?> publishProgress(
-            final ProgressListener listener,
-            final ProgressEventType type) {
-        if (listener == ProgressListener.NOOP || listener == null
-        ||  type == null) {
-            return null;
-        }
-        return deliverEvent(listener, new ProgressEvent(type));
-    }
-
-    private static Future<?> deliverEvent(final ProgressListener listener,
-            final ProgressEvent event) {
-
-        if (listener instanceof DeliveryMode) {
-            DeliveryMode mode = (DeliveryMode) listener;
-            if (mode.isSyncCallSafe()) {
-                // Safe to call the listener directly
-                return quietlyCallListener(listener, event);
-            }
-        }
-        // Not safe to call the listener directly; so submit an async task.
-        // This is unfortunate as the listener should never block in the first
-        // place, but such task submission is necessary to remain backward
-        // compatible.
-        return latestFutureTask = LazyHolder.executor.submit(new Runnable() {
-            @Override
-            public void run() {
-                listener.progressChanged(event);
-            }
-        });
-    }
-
-    private static Future<?> quietlyCallListener(final ProgressListener listener,
-            final ProgressEvent event) {
-        try {
-            listener.progressChanged(event);
-        } catch(Throwable t) {
-            // That's right, we need to suppress all errors so as to be on par
-            // with the async mode where all failures will be ignored.
-            LogFactory.getLog(SDKProgressPublisher.class)
-                .debug("Failure from the event listener", t);
-        }
-        return null;
-    }
-
-    /**
-     * Convenient method to publish a request content length event to the given
-     * listener.
-     *
-     * @param listener
-     *            must not be null or else the publication will be skipped
-     * @param bytes
-     *            must be non-negative or else the publication will be skipped
-     */
-    public static Future<?> publishRequestContentLength(
-            final ProgressListener listener,
-            final long bytes) {
-        return publishByteCountEvent(listener, REQUEST_CONTENT_LENGTH_EVENT, bytes);
-    }
-
-    /**
-     * Convenient method to publish a response content length event to the given
-     * listener.
-     *
-     * @param listener
-     *            must not be null or else the publication will be skipped
-     * @param bytes
-     *            must be non-negative or else the publication will be skipped
-     */
-    public static Future<?> publishResponseContentLength(
-            final ProgressListener listener,
-            final long bytes) {
-        return publishByteCountEvent(listener, RESPONSE_CONTENT_LENGTH_EVENT, bytes);
-    }
-
-    /**
-     * Convenient method to publish a request byte transfer event to the given
-     * listener.
-     *
-     * @param listener
-     *            must not be null or else the publication will be skipped
-     * @param bytes
-     *            must be non-negative or else the publication will be skipped
-     */
-    public static Future<?> publishRequestBytesTransferred(
-            final ProgressListener listener,
-            final long bytes) {
-        return publishByteCountEvent(listener, REQUEST_BYTE_TRANSFER_EVENT, bytes);
-    }
-
-    /**
-     * Convenient method to publish a response byte transfer event to the given
-     * listener.
-     *
-     * @param listener
-     *            must not be null or else the publication will be skipped
-     * @param bytes
-     *            must be non-negative or else the publication will be skipped
-     */
-    public static Future<?> publishResponseBytesTransferred(
-            final ProgressListener listener,
-            final long bytes) {
-        return publishByteCountEvent(listener, RESPONSE_BYTE_TRANSFER_EVENT, bytes);
-    }
-
-    private static Future<?> publishByteCountEvent(
-            final ProgressListener listener,
-            final ProgressEventType type,
-            final long bytes) {
-        if (listener == ProgressListener.NOOP || listener == null || bytes <= 0)
-            return null;
-        return deliverEvent(listener, new ProgressEvent(type, bytes));
-    }
-
-    /**
-     * Convenient method to publish a request reset event to the given listener.
-     *
-     * @param listener
-     *            must not be null or else the publication will be skipped
-     * @param bytesReset
-     *            must be non-negative or else the publication will be skipped
-     */
-    public static Future<?> publishRequestReset(
-            final ProgressListener listener,
-            final long bytesReset) {
-        return publishResetEvent(listener, HTTP_REQUEST_CONTENT_RESET_EVENT, bytesReset);
-    }
-
-    /**
-     * Convenient method to publish a response reset event to the given listener.
-     */
-    public static Future<?> publishResponseReset(
-            final ProgressListener listener,
-            final long bytesReset) {
-        return publishResetEvent(listener, HTTP_RESPONSE_CONTENT_RESET_EVENT, bytesReset);
-    }
-
-    /**
-     * Convenient method to publish a response bytes discard event to the given listener.
-     */
-    public static Future<?> publishResponseBytesDiscarded(
-            final ProgressListener listener,
-            final long bytesDiscarded) {
-        return publishResetEvent(listener,
-                ProgressEventType.RESPONSE_BYTE_DISCARD_EVENT, bytesDiscarded);
-    }
-
-    /**
-     * @param listener
-     *            must not be null or else the publication will be skipped
-     * @param bytesReset
-     *            the publication will be skipped unless the number of bytes
-     *            reset is positive
-     */
-    private static Future<?> publishResetEvent(
-            final ProgressListener listener,
-            final ProgressEventType resetEventType,
-            final long bytesReset) {
-        if (bytesReset <= 0)
-            return null;
-        if (listener == ProgressListener.NOOP || listener == null)
-            return null;
-        return deliverEvent(listener, new ProgressEvent(resetEventType, bytesReset));
-    }
-
-    /**
-     * Returns the executor service used for performing the callbacks.
-     */
-    protected static ExecutorService getExecutorService() {
-        return LazyHolder.executor;
-    }
-
-    protected static Future<?> setLatestFutureTask(Future<?> f) {
-        return latestFutureTask = f;
-    }
-
-    /**
-     * For internal testing and backward compatibility only. This method blocks
-     * until all the submitted callbacks are executed. Listeners should never
-     * block so this method should never be used.
-     */
-    @Deprecated
-    public static void waitTillCompletion()
-            throws InterruptedException, ExecutionException {
-        if (latestFutureTask != null) {
-            latestFutureTask.get();
-        }
-    }
-
-    /**
-     * Used to avoid creating the extra thread until absolutely necessary.
-     */
-    private static final class LazyHolder {
-        /** A single thread pool for executing all ProgressListener callbacks. **/
-        private static final ExecutorService executor = createNewExecutorService();
-
-        /**
-         * Creates a new single threaded executor service for performing the
-         * callbacks.
-         */
-        private static ExecutorService createNewExecutorService() {
-            return Executors.newSingleThreadExecutor(new ThreadFactory() {
-                public Thread newThread(Runnable r) {
-                    Thread t = new Thread(r);
-                    t.setName("java-sdk-progress-listener-callback-thread");
-                    t.setDaemon(true);
-                    return t;
-                }
-            });
-        }
-    }
-
-    /**
-     * Can be used to shutdown the (legacy) executor.
-     * <p>
-     * However, the recommended best practice is to always make use of progress
-     * listeners that are short-lived (ie do not block) and are subclasses of
-     * either {@link SyncProgressListener} or
-     * <code>S3SyncProgressListener</code>. That way, the progress publisher
-     * (legacy) thread will never be activated in the first place.
-     *
-     * @param now true if shutdown now; false otherwise.
-     */
-    public static void shutdown(boolean now) {
-        if (now)
-            LazyHolder.executor.shutdownNow();
-        else
-            LazyHolder.executor.shutdown();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/event/SyncProgressListener.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/SyncProgressListener.java
--- ./src/main/java/com/amazonaws/event/SyncProgressListener.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/event/SyncProgressListener.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.event;
-
-/**
- * Abstract adapter class for a progress listener that is delivered with
- * progress event synchronously. 
- */
-public abstract class SyncProgressListener
-    implements ProgressListener, DeliveryMode {
-    /**
-     * Always returns true.
-     */
-    @Override public boolean isSyncCallSafe() { return true; }
-}
diff -Nau8r ./src/main/java/com/amazonaws/HandlerContextAware.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/HandlerContextAware.java
--- ./src/main/java/com/amazonaws/HandlerContextAware.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/HandlerContextAware.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws;
-
-import com.amazonaws.handlers.HandlerContextKey;
-
-/**
- * An implementing object is capable of storing context that is visible to all {@link com.amazonaws.handlers.RequestHandler2}.
- *
- * <p>This interface is subject to change and should not be implemented by users of the SDK.</p>
- */
-public interface HandlerContextAware {
-    /**
-     * Adds a context to that is visible to all {@link com.amazonaws.handlers.RequestHandler2}s.
-     *
-     * Note that, context added here will available only for the scope of
-     * the request execution and will not be marshalled over the wire.
-     * @param key the key for the property being set in the request.
-     * @param value the value for the property being set in the request.
-     */
-    <X> void addHandlerContext(HandlerContextKey<X> key, X value);
-
-    /**
-     * Return the context for the given key if present; else return null.
-     *
-     * @param key the key for the context
-     * @return the context if present else null.
-     */
-    <X> X getHandlerContext(HandlerContextKey<X> key);
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/AbstractRequestHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/AbstractRequestHandler.java
--- ./src/main/java/com/amazonaws/handlers/AbstractRequestHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/AbstractRequestHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.Request;
-import com.amazonaws.util.TimingInfo;
-
-/**
- * @deprecated by {@link RequestHandler2}.
- * <p>
- * Simple implementation of RequestHandler to stub out required methods.
- */
-@Deprecated
-public abstract class AbstractRequestHandler implements RequestHandler {
-	public void beforeRequest(Request<?> request) {}
-	public void afterResponse(Request<?> request, Object response, TimingInfo timingInfo) {}
-	public void afterError(Request<?> request, Exception e) {}
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/AsyncHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/AsyncHandler.java
--- ./src/main/java/com/amazonaws/handlers/AsyncHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/AsyncHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.AmazonWebServiceRequest;
-
-/**
- * Callback interface for notification on web service requests executed with the
- * asynchronous clients in the AWS SDK for Java.
- */
-public interface AsyncHandler<REQUEST extends AmazonWebServiceRequest, RESULT> {
-
-	/**
-	 * Invoked after an asynchronous request 
-	 * @param exception
-	 */
-	public void onError(Exception exception);
-
-	/**
-	 * Invoked after an asynchronous request has completed successfully. Callers
-	 * have access to the original request object and the returned response
-	 * object.
-	 *
-	 * @param request
-	 *            The initial request created by the caller
-	 * @param result
-	 *            The successful result of the executed operation.
-	 */
-	public void onSuccess(REQUEST request, RESULT result);
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/handlers/CredentialsRequestHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/CredentialsRequestHandler.java
--- ./src/main/java/com/amazonaws/handlers/CredentialsRequestHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/CredentialsRequestHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.auth.AWSCredentials;
-
-/**
- * A special type of
- * <code>RequestHandler2</code> that takes in <code>AWSCredentials</code>.
- *
- * @deprecated Use of this class to retrieve the credentials is unsafe in
- * multithreading scenarios. If a client is used across multiple threads,
- * there's a possibility of running into a race condition where one handler
- * might access the credentials through the reference as another thread is
- * updating it. Retrieve the credentials from the handler context instead using
- * the {@link HandlerContextKey#AWS_CREDENTIALS} key.
- */
-@Deprecated
-public abstract class CredentialsRequestHandler extends RequestHandler2 {
-
-    /** AWSCredentials to be used in the RequestHandler. */
-    protected AWSCredentials awsCredentials;
-
-    /**
-     * Sets the AWSCredentials.
-     */
-    public void setCredentials(AWSCredentials awsCredentials) {
-        this.awsCredentials = awsCredentials;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/HandlerAfterAttemptContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerAfterAttemptContext.java
--- ./src/main/java/com/amazonaws/handlers/HandlerAfterAttemptContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerAfterAttemptContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,146 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.handlers;
-
-import com.amazonaws.Request;
-import com.amazonaws.Response;
-
-/**
- * Contextual data for the RequestHandler2 afterAttempt callback
- *
- * Under certain conditions (redirects), both response and exception may be null
- */
-public final class HandlerAfterAttemptContext {
-
-    /**
-     * The request being attempted
-     */
-    private final Request<?> request;
-
-    /**
-     * The response returned by the request; null if the request was not successful
-     */
-    private final Response<?> response;
-
-    /**
-     * Exception generated while processing the request; possibly null
-     */
-    private final Exception exception;
-
-    /**
-     * Default constructor for the HandlerAfterAttemptContext class
-     */
-    private HandlerAfterAttemptContext(Request<?> request, Response<?> response, Exception exception) {
-        this.request = request;
-        this.response = response;
-        this.exception = exception;
-    }
-
-    /**
-     * @return the request being attempted
-     */
-    public Request<?> getRequest() {
-        return request;
-    }
-
-    /**
-     * @return the response to the request or null if the attempt failed
-     */
-    public Response<?> getResponse() {
-        return response;
-    }
-
-    /**
-     * @return the exception that was generated while processing the request, or null if the attempt succeeded
-     */
-    public Exception getException() {
-        return exception;
-    }
-
-
-    /**
-     * @return a new builder for a HandlerAfterAttemptContext instance
-     */
-    public static HandlerAfterAttemptContextBuilder builder() {
-        return new HandlerAfterAttemptContextBuilder();
-    }
-
-    /**
-     * Builder class for HandlerAfterAttemptContext
-     */
-    public static class HandlerAfterAttemptContextBuilder {
-
-        /**
-         * The request being attempted
-         */
-        private Request<?> request;
-
-        /**
-         * The response returned by the request; null if the request was not successful
-         */
-        private Response<?> response;
-
-        /**
-         * Exception generated while processing the request; possibly null
-         */
-        private Exception exception;
-
-        /**
-         * Default constructor
-         */
-        private HandlerAfterAttemptContextBuilder() {}
-
-        /**
-         * Fluent set for what the request should be on the eventual HandlerAfterAttemptContext instance
-         * @param request the request that was attempted
-         * @return the modified builder
-         */
-        public HandlerAfterAttemptContextBuilder withRequest(Request<?> request) {
-            this.request = request;
-
-            return this;
-        }
-
-        /**
-         * Fluent set for what the response should be on the eventual HandlerAfterAttemptContext instance
-         * @param response response from the request attempt, or null if there was an error
-         * @return the modified builder
-         */
-        public HandlerAfterAttemptContextBuilder withResponse(Response<?> response) {
-            this.response = response;
-
-            return this;
-        }
-
-        /**
-         * Fluent set for what the exception should be on the eventual HandlerAfterAttemptContext instance
-         * @param exception exception generated by the request attempt, or null if the attempt was succcessful
-         * @return the modified builder
-         */
-        public HandlerAfterAttemptContextBuilder withException(Exception exception) {
-            this.exception = exception;
-
-            return this;
-        }
-
-        /**
-         * @return a new HandlerAfterAttemptContext object
-         */
-        public HandlerAfterAttemptContext build() {
-            return new HandlerAfterAttemptContext(request, response, exception);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/HandlerBeforeAttemptContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerBeforeAttemptContext.java
--- ./src/main/java/com/amazonaws/handlers/HandlerBeforeAttemptContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerBeforeAttemptContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,85 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.handlers;
-
-import com.amazonaws.Request;
-
-/**
- * Contextual data for the RequestHandler2 beforeAttempt callback
- */
-public final class HandlerBeforeAttemptContext {
-
-    /**
-     * The request being attempted
-     */
-    private final Request<?> request;
-
-    /**
-     * Default constructor for the HandlerBeforeAttemptContext object
-     */
-    private HandlerBeforeAttemptContext(Request<?> request) {
-        this.request = request;
-    }
-
-    /**
-     * @return the request that is about to be attempted
-     */
-    public Request<?> getRequest() {
-        return request;
-    }
-
-
-    /**
-     * @return a new builder for a HandlerBeforeAttemptContext instance
-     */
-    public static HandlerBeforeAttemptContextBuilder builder() {
-        return new HandlerBeforeAttemptContextBuilder();
-    }
-
-    /**
-     * Builder class for HandlerBeforeAttemptContext
-     */
-    public static class HandlerBeforeAttemptContextBuilder {
-
-        /**
-         * The request being attempted
-         */
-        private Request<?> request;
-
-        /**
-         * Default constructor
-         */
-        private HandlerBeforeAttemptContextBuilder() {}
-
-        /**
-         * Fluent set for what the request should be on the eventual HandlerBeforeAttemptContext instance
-         * @param request the request that is to be attempted
-         * @return the modified builder
-         */
-        public HandlerBeforeAttemptContextBuilder withRequest(Request<?> request) {
-            this.request = request;
-
-            return this;
-        }
-
-        /**
-         * @return a new HandlerBeforeAttemptContext object
-         */
-        public HandlerBeforeAttemptContext build() {
-            return new HandlerBeforeAttemptContext(request);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/HandlerChainFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerChainFactory.java
--- ./src/main/java/com/amazonaws/handlers/HandlerChainFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerChainFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,169 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.util.ClassLoaderHelper;
-import com.amazonaws.util.StringUtils;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-
-/**
- * Factory for creating request/response handler chains.
- */
-public class HandlerChainFactory {
-
-    private static final String GLOBAL_HANDLER_PATH = "com/amazonaws/global/handlers/request.handler2s";
-
-    /**
-     * For backward compatibility, constructs a new request handler chain adapted to {@link RequestHandler2} by analyzing the
-     * specified classpath resource.
-     *
-     * @param resource The resource to load from the classpath containing the list of request handlers to instantiate.
-     * @return A list of request handlers based on the handlers referenced in the specified resource.
-     */
-    public List<RequestHandler2> newRequestHandlerChain(String resource) {
-        return createRequestHandlerChain(resource, RequestHandler.class);
-    }
-
-    /**
-     * Constructs a new request handler (v2) chain by analyzing the specified classpath resource.
-     *
-     * @param resource The resource to load from the classpath containing the list of request handlers to instantiate.
-     * @return A list of request handlers based on the handlers referenced in the specified resource.
-     */
-    public List<RequestHandler2> newRequestHandler2Chain(String resource) {
-        return createRequestHandlerChain(resource, RequestHandler2.class);
-    }
-
-    public List<RequestHandler2> getGlobalHandlers() {
-        List<RequestHandler2> handlers = new ArrayList<RequestHandler2>();
-        BufferedReader fileReader = null;
-
-        try {
-            List<URL> globalHandlerListLocations = Collections
-                    .list(getGlobalHandlerResources());
-
-            for (URL url : globalHandlerListLocations) {
-
-                fileReader = new BufferedReader(new InputStreamReader(url.openStream(), StringUtils.UTF8));
-                while (true) {
-                    String requestHandlerClassName = fileReader.readLine();
-                    if (requestHandlerClassName == null) {
-                        break;
-                    }
-                    RequestHandler2 requestHandler = createRequestHandler(requestHandlerClassName, RequestHandler2.class);
-                    if (requestHandler == null) {
-                        continue;
-                    }
-                    handlers.add(requestHandler);
-                }
-            }
-
-        } catch (Exception e) {
-            throw new AmazonClientException("Unable to instantiate request handler chain for client: "
-                                            + e.getMessage(), e);
-        } finally {
-            try {
-                if (fileReader != null) {
-                    fileReader.close();
-                }
-            } catch (IOException e) {
-            }
-        }
-        return handlers;
-    }
-
-    private Enumeration<URL> getGlobalHandlerResources() throws IOException {
-        // Classloader may be null if loaded by bootstrap classloader.
-        if (HandlerChainFactory.class.getClassLoader() == null) {
-            return ClassLoader.getSystemResources(GLOBAL_HANDLER_PATH);
-        }
-        return HandlerChainFactory.class.getClassLoader().getResources(GLOBAL_HANDLER_PATH);
-    }
-
-    private RequestHandler2 createRequestHandler(String handlerClassName, Class<?> handlerApiClass)
-            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
-        handlerClassName = handlerClassName.trim();
-        if (handlerClassName.equals("")) {
-            return null;
-        }
-        Class<?> requestHandlerClass = ClassLoaderHelper.loadClass(
-                handlerClassName,
-                handlerApiClass, getClass());
-        Object requestHandlerObject = requestHandlerClass.newInstance();
-        if (handlerApiClass.isInstance(requestHandlerObject)) {
-            if (handlerApiClass == RequestHandler2.class) {
-                return (RequestHandler2) requestHandlerObject;
-
-            } else if (handlerApiClass == RequestHandler.class) {
-                return RequestHandler2.adapt((RequestHandler) requestHandlerObject);
-
-            } else {
-                throw new IllegalStateException();
-            }
-        } else {
-            throw new AmazonClientException(
-                    "Unable to instantiate request handler chain for client.  "
-                    + "Listed request handler ('"
-                    + handlerClassName + "') "
-                    + "does not implement the "
-                    + handlerApiClass + " API.");
-        }
-    }
-
-    private List<RequestHandler2> createRequestHandlerChain(String resource, Class<?> handlerApiClass) {
-        List<RequestHandler2> handlers = new ArrayList<RequestHandler2>();
-        BufferedReader reader = null;
-
-        try {
-            InputStream input = getClass().getResourceAsStream(resource);
-            if (input == null) {
-                return handlers;
-            }
-
-            reader = new BufferedReader(new InputStreamReader(input, StringUtils.UTF8));
-            while (true) {
-                String requestHandlerClassName = reader.readLine();
-                if (requestHandlerClassName == null) {
-                    break;
-                }
-                RequestHandler2 requestHandler = createRequestHandler(requestHandlerClassName, handlerApiClass);
-                if (requestHandler == null) {
-                    continue;
-                }
-                handlers.add(requestHandler);
-            }
-        } catch (Exception e) {
-            throw new AmazonClientException("Unable to instantiate request handler chain for client: "
-                                            + e.getMessage(), e);
-        } finally {
-            try {
-                if (reader != null) {
-                    reader.close();
-                }
-            } catch (IOException e) {
-            }
-        }
-        return handlers;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/HandlerContextKey.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerContextKey.java
--- ./src/main/java/com/amazonaws/handlers/HandlerContextKey.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/HandlerContextKey.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,85 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.auth.AWSCredentials;
-
-/**
- * A type safe key used for setting and retrieving context in a {@link
- * com.amazonaws.Request} object.
- *
- * <pre class="brush: java">
- *     final HandlerContextKey<String> METRICS_KEY = new HandlerContextKey("METRICS_KEY");
- *
- *      new RequestHandler2(){
- *
- *          @Override
- *          public void beforeRequest(Request<?> request) {
- *              request.addHandlerContext(METRICS_KEY, AWSRequestMetrics
- *                                                  .Field.HttpRequestTime.name());
- *          }
- *
- *          @Override
- *          public void afterResponse(Request<?> request, Response<?> response) {
- *              String metricsKey = request.getHandlerContext(METRICS_KEY);
- *          }
- *
- *          @Override
- *          public void afterError(Request<?> request, Response<?> response,
- *          Exception e) { }
- *      }
- * </pre>
- */
-public class HandlerContextKey<T> {
-
-    /**
-     * The key under which the request credentials are set.
-     **/
-    public static final HandlerContextKey<AWSCredentials> AWS_CREDENTIALS = new HandlerContextKey<AWSCredentials>("AWSCredentials");
-
-    /**
-     * The region used to sign the request.
-     */
-    public static final HandlerContextKey<String> SIGNING_REGION = new HandlerContextKey<String>("SigningRegion");
-
-    private final String name;
-
-    public HandlerContextKey(String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("Name cannot be null");
-        }
-        this.name = name;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        HandlerContextKey<?> key = (HandlerContextKey<?>) o;
-
-        return name.equals(key.getName());
-
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/IRequestHandler2.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/IRequestHandler2.java
--- ./src/main/java/com/amazonaws/handlers/IRequestHandler2.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/IRequestHandler2.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.handlers;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.Response;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.HttpResponse;
-
-/**
- * Interface for {@link RequestHandler2}. Do not use this outside the core SDK. We can and will add
- * methods to this interface in the future. Extend {@link RequestHandler2} to implement a custom
- * request handler.
- */
-@SdkInternalApi
-public interface IRequestHandler2 {
-    /**
-     * Runs any additional processing logic on the specified request object as soon as the request
-     * is provided to the service client.
-     *
-     * <p>This request handler is excluded from the client execution time metrics and is run on the
-     * application's thread, even for asynchronous requests.</p>
-     *
-     * <p>Warning: Modifications to this message will leak out to the user, who might reuse the request
-     * object without realizing that it was modified as part of sending it the first time. For this
-     * reason, we recommend that you only modify the request in the {@link #beforeRequest(Request)}
-     * method. If you require data that is not available in that method, you should create a
-     * {@link AmazonWebServiceRequest#clone()} of the request (which performs a deep copy of the
-     * handler context map), add any context data you require in the {@link #beforeRequest(Request)}
-     * method using {@link AmazonWebServiceRequest#addHandlerContext(HandlerContextKey, Object)}, and
-     * return your cloned message from this method. You can then extract that data for use in the
-     * request using {@link Request#getHandlerContext(HandlerContextKey)}.</p>
-     *
-     * @param request the request passed in by the user
-     * @return the (possibly different) request to execute
-     */
-    AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest request);
-
-    /**
-     * Runs any additional processing logic on the specified request object before it is marshaled
-     * into an HTTP request.
-     *
-     * <p>Warning: Modifications to this message will leak out to the user, who might reuse the request
-     * object without realizing that it was modified as part of sending it the first time. For this
-     * reason, we recommend that you only modify the request in the {@link #beforeRequest(Request)}
-     * method. If you require data that is not available in that method, you should create a
-     * {@link AmazonWebServiceRequest#clone()} of the request (which performs a deep copy of the
-     * handler context map), add any context data you require in the {@link #beforeRequest(Request)}
-     * method using {@link AmazonWebServiceRequest#addHandlerContext(HandlerContextKey, Object)}, and
-     * return your cloned message from this method. You can then extract that data for use in the
-     * request using {@link Request#getHandlerContext(HandlerContextKey)}.</p>
-     *
-     * @param request
-     *            the request passed in by the user
-     * @return the (possibly different) request to marshal
-     */
-    AmazonWebServiceRequest beforeMarshalling(AmazonWebServiceRequest request);
-
-    /**
-     * Runs any additional processing logic on the specified request (before it is executed by the
-     * client runtime).
-     *
-     * @param request
-     *            The low level request being processed.
-     */
-    void beforeRequest(Request<?> request);
-
-    /**
-     * Runs any additional processing logic on a request before each individual attempt is made.
-     *
-     * @param context
-     *              container for callback-related data; includes the request
-     */
-    void beforeAttempt(HandlerBeforeAttemptContext context);
-
-    /**
-     * Runs any additional processing logic on the specified response before it's unmarshalled. This
-     * callback is only invoked on successful responses that will be unmarshalled into an
-     * appropriate modeled class and not for unsuccessful responses that will be unmarshalled into a
-     * subclass of {@link AmazonServiceException}
-     *
-     * @param request
-     *            The low level request being processed.
-     * @param httpResponse
-     *            The Raw HTTP response before being unmarshalled
-     * @return {@link HttpResponse} to replace the actual response. May be a mutated version of the
-     *         original or a completely new {@link HttpResponse} object
-     */
-    HttpResponse beforeUnmarshalling(Request<?> request, HttpResponse httpResponse);
-
-    /**
-     * Runs any additional processing logic on a request after each individual attempt.  Callback is
-     * invoked whether or not the attempt resulted in a successful response or an error.  This callback
-     * is invoked within a finally block and so any exceptions it generates will "replace" the current
-     * exception, if one is outstanding.
-     *
-     * @param context
-     *              container for the request as well as all possible results of the attempt
-     */
-    void afterAttempt(HandlerAfterAttemptContext context);
-
-    /**
-     * Runs any additional processing logic on the specified request (after is has been executed by
-     * the client runtime).
-     *
-     * @param request
-     *            The low level request being processed.
-     * @param response
-     *            The response generated from the specified request.
-     */
-    void afterResponse(Request<?> request, Response<?> response);
-
-    /**
-     * Runs any additional processing logic on a request after it has failed.  This callback is invoked
-     * from a catch block.  If it generates an exception, the original AmazonClientException will be lost.
-     *
-     * @param request
-     *            The request that generated an error.
-     * @param response
-     *            the response or null if the failure occurred before the response is made available
-     * @param e
-     *            The error that resulted from executing the request.
-     */
-    void afterError(Request<?> request, Response<?> response, Exception e);
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/RequestHandler2Adaptor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/RequestHandler2Adaptor.java
--- ./src/main/java/com/amazonaws/handlers/RequestHandler2Adaptor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/RequestHandler2Adaptor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,68 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.Request;
-import com.amazonaws.Response;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.TimingInfo;
-
-/**
- * Internal class used to adapt a request handler that implements the
- * deprecated {@link RequestHandler} interface to the deprecating
- * {@link RequestHandler2} interface.
- */
-final class RequestHandler2Adaptor extends RequestHandler2 {
-    @SuppressWarnings("deprecation")
-    private final RequestHandler old;
-    RequestHandler2Adaptor(@SuppressWarnings("deprecation") RequestHandler old) {
-        if (old == null)
-            throw new IllegalArgumentException();
-        this.old = old;
-    }
-    @SuppressWarnings("deprecation")
-    @Override public void beforeRequest(Request<?> request) {
-        old.beforeRequest(request);
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void afterResponse(Request<?> request, Response<?> response) {
-        AWSRequestMetrics awsRequestMetrics = request == null ? null : request
-                .getAWSRequestMetrics();
-        Object awsResponse = response == null ? null : response
-                .getAwsResponse();
-        TimingInfo timingInfo = awsRequestMetrics == null ? null
-                : awsRequestMetrics.getTimingInfo();
-        old.afterResponse(request, awsResponse, timingInfo);
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override public void afterError(Request<?> request, Response<?> response,
-            Exception e) {
-        old.afterError(request, e);
-    }
-
-    @Override public int hashCode() {
-        return old.hashCode();
-    }
-
-    @Override public boolean equals(Object o) {
-        if (!(o instanceof RequestHandler2Adaptor))
-            return false;
-        RequestHandler2Adaptor that = (RequestHandler2Adaptor)o;
-        return this.old.equals(that.old);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/RequestHandler2.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/RequestHandler2.java
--- ./src/main/java/com/amazonaws/handlers/RequestHandler2.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/RequestHandler2.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.Response;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.util.TimingInfo;
-
-/**
- * Interface for addition request handling in clients. A request handler is executed on a request
- * object <b>before</b> it is sent to the client runtime to be executed.
- * <p>
- * This interface deprecates {@link RequestHandler} by providing access to not only the AWS
- * response, but also the associated http response via {@link Response}.
- * <p>
- * Note {@link TimingInfo} is accessible via {@link Request#getAWSRequestMetrics()} and hence is
- * omitted from the interface to reduce duplication by design.
- */
-public abstract class RequestHandler2 implements IRequestHandler2 {
-
-    @Override
-    public AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest request) {
-        return request;
-    }
-
-    @Override
-    public AmazonWebServiceRequest beforeMarshalling(AmazonWebServiceRequest request) {
-        return request;
-    }
-
-    @Override
-    public void beforeRequest(Request<?> request) {
-    }
-
-    @Override
-    public void beforeAttempt(HandlerBeforeAttemptContext context) {
-    }
-
-    @Override
-    public HttpResponse beforeUnmarshalling(Request<?> request, HttpResponse httpResponse) {
-        return httpResponse;
-    }
-
-    @Override
-    public void afterAttempt(HandlerAfterAttemptContext context) {
-    }
-
-    @Override
-    public void afterResponse(Request<?> request, Response<?> response) {
-    }
-
-    @Override
-    public void afterError(Request<?> request, Response<?> response, Exception e) {
-    }
-
-    /**
-     * Returns an instance of request handler adapted to the {@link RequestHandler2} interface from
-     * the given request handler implementing the deprecated {@link RequestHandler} interface.
-     */
-    public static RequestHandler2 adapt(@SuppressWarnings("deprecation") RequestHandler old) {
-        return new RequestHandler2Adaptor(old);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/RequestHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/RequestHandler.java
--- ./src/main/java/com/amazonaws/handlers/RequestHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/RequestHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,62 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.Request;
-import com.amazonaws.util.TimingInfo;
-
-/**
- * @deprecated by {@link RequestHandler2}.
- *  
- * Interface for addition request handling in clients. A request handler is
- * executed on a request object <b>before</b> it is sent to the client runtime
- * to be executed.
- */
-@Deprecated
-public interface RequestHandler {
-
-    /**
-     * Runs any additional processing logic on the specified request (before it
-     * is executed by the client runtime).
-     *
-     * @param request
-     *            The low level request being processed.
-     */
-    public void beforeRequest(Request<?> request);
-
-	/**
-	 * Runs any additional processing logic on the specified request (after is
-	 * has been executed by the client runtime).
-	 *
-	 * @param request
-	 *            The low level request being processed.
-	 * @param response
-	 *            The response generated from the specified request.
-	 * @param timingInfo
-	 *            Timing information on the request's processing.
-	 */
-    public void afterResponse(Request<?> request, Object response, TimingInfo timingInfo);
-
-	/**
-	 * Runs any additional processing logic on a request after it has failed.
-	 *
-	 * @param request
-	 *            The request that generated an error.
-	 * @param e
-	 *            The error that resulted from executing the request.
-	 */
-    public void afterError(Request<?> request, Exception e);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/handlers/StackedRequestHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/StackedRequestHandler.java
--- ./src/main/java/com/amazonaws/handlers/StackedRequestHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/handlers/StackedRequestHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,131 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.handlers;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.Response;
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.util.ValidationUtils;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Composite {@link RequestHandler2} to execute a chain of {@link RequestHandler2} implementations
- * in stack order. That is if you have request handlers R1, R2, R3 the order of execution is as
- * follows
- * 
- * <pre>
- *    
- * {@code   
- * R1.beforeMarshalling   
- * R2.beforeMarshalling   
- * R3.beforeMarshalling   
- *    
- * R1.beforeRequest   
- * R2.beforeRequest   
- * R3.beforeRequest   
- *    
- * R3.beforeUnmarshalling
- * R2.beforeUnmarshalling
- * R1.beforeUnmarshalling
- * 
- * R3.after(Response|Error)   
- * R2.after(Response|Error)   
- * R1.after(Response|Error)   
- * }
- * </pre>
- */
-@ThreadSafe
-public class StackedRequestHandler implements IRequestHandler2 {
-
-    private final List<RequestHandler2> inOrderRequestHandlers;
-    private final List<RequestHandler2> reverseOrderRequestHandlers;
-
-    public StackedRequestHandler(RequestHandler2...requestHandlers) {
-       this(Arrays.asList(ValidationUtils.assertNotNull(requestHandlers, "requestHandlers")));
-    }
-
-    public StackedRequestHandler(List<RequestHandler2> requestHandlers) {
-        this.inOrderRequestHandlers = ValidationUtils.assertNotNull(requestHandlers, "requestHandlers");
-        this.reverseOrderRequestHandlers = new ArrayList<RequestHandler2>(requestHandlers);
-        Collections.reverse(reverseOrderRequestHandlers);
-    }
-
-    @Override
-    public AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest origRequest) {
-        AmazonWebServiceRequest toReturn = origRequest;
-        for (RequestHandler2 handler : inOrderRequestHandlers) {
-            toReturn = handler.beforeExecution(toReturn);
-        }
-        return toReturn;
-    }
-
-    @Override
-    public AmazonWebServiceRequest beforeMarshalling(AmazonWebServiceRequest origRequest) {
-        AmazonWebServiceRequest toReturn = origRequest;
-        for (RequestHandler2 handler : inOrderRequestHandlers) {
-            toReturn = handler.beforeMarshalling(toReturn);
-        }
-        return toReturn;
-    }
-
-    @Override
-    public void beforeRequest(Request<?> request) {
-        for (RequestHandler2 handler : inOrderRequestHandlers) {
-            handler.beforeRequest(request);
-        }
-    }
-
-    @Override
-    public void beforeAttempt(HandlerBeforeAttemptContext context) {
-        for (RequestHandler2 handler : inOrderRequestHandlers) {
-            handler.beforeAttempt(context);
-        }
-    }
-
-    @Override
-    public HttpResponse beforeUnmarshalling(Request<?> request, HttpResponse origHttpResponse) {
-        HttpResponse toReturn = origHttpResponse;
-        for(RequestHandler2 handler : reverseOrderRequestHandlers) {
-            toReturn = handler.beforeUnmarshalling(request, toReturn);
-        }
-        return toReturn;
-    }
-
-    @Override
-    public void afterAttempt(HandlerAfterAttemptContext context) {
-        for(RequestHandler2 handler : reverseOrderRequestHandlers) {
-            handler.afterAttempt(context);
-        }
-    }
-
-    @Override
-    public void afterResponse(Request<?> request, Response<?> response) {
-        for(RequestHandler2 handler : reverseOrderRequestHandlers) {
-            handler.afterResponse(request, response);
-        }
-    }
-
-    @Override
-    public void afterError(Request<?> request, Response<?> response, Exception e) {
-        for(RequestHandler2 handler : reverseOrderRequestHandlers) {
-            handler.afterError(request, response, e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/AmazonHttpClient.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/AmazonHttpClient.java
--- ./src/main/java/com/amazonaws/http/AmazonHttpClient.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/AmazonHttpClient.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,1846 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import static com.amazonaws.SDKGlobalConfiguration.PROFILING_SYSTEM_PROPERTY;
-import static com.amazonaws.event.SDKProgressPublisher.publishProgress;
-import static com.amazonaws.event.SDKProgressPublisher.publishRequestContentLength;
-import static com.amazonaws.event.SDKProgressPublisher.publishResponseContentLength;
-import static com.amazonaws.util.AWSRequestMetrics.Field.HttpClientPoolAvailableCount;
-import static com.amazonaws.util.AWSRequestMetrics.Field.HttpClientPoolLeasedCount;
-import static com.amazonaws.util.AWSRequestMetrics.Field.HttpClientPoolPendingCount;
-import static com.amazonaws.util.AWSRequestMetrics.Field.ThrottledRetryCount;
-import static com.amazonaws.util.IOUtils.closeQuietly;
-
-import com.amazonaws.AbortedException;
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.AmazonWebServiceResponse;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.Request;
-import com.amazonaws.RequestClientOptions;
-import com.amazonaws.RequestClientOptions.Marker;
-import com.amazonaws.RequestConfig;
-import com.amazonaws.ResetException;
-import com.amazonaws.Response;
-import com.amazonaws.ResponseMetadata;
-import com.amazonaws.SDKGlobalTime;
-import com.amazonaws.SdkBaseException;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.CanHandleNullCredentials;
-import com.amazonaws.auth.Signer;
-import com.amazonaws.event.ProgressEventType;
-import com.amazonaws.event.ProgressInputStream;
-import com.amazonaws.event.ProgressListener;
-import com.amazonaws.handlers.CredentialsRequestHandler;
-import com.amazonaws.handlers.HandlerAfterAttemptContext;
-import com.amazonaws.handlers.HandlerBeforeAttemptContext;
-import com.amazonaws.handlers.HandlerContextKey;
-import com.amazonaws.handlers.RequestHandler2;
-import com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory;
-import com.amazonaws.http.apache.client.impl.ConnectionManagerAwareHttpClient;
-import com.amazonaws.http.apache.request.impl.ApacheHttpRequestFactory;
-import com.amazonaws.http.apache.utils.ApacheUtils;
-import com.amazonaws.http.client.HttpClientFactory;
-import com.amazonaws.http.exception.HttpRequestTimeoutException;
-import com.amazonaws.http.request.HttpRequestFactory;
-import com.amazonaws.http.response.AwsResponseHandlerAdapter;
-import com.amazonaws.http.settings.HttpClientSettings;
-import com.amazonaws.http.timers.client.ClientExecutionAbortTrackerTask;
-import com.amazonaws.http.timers.client.ClientExecutionTimeoutException;
-import com.amazonaws.http.timers.client.ClientExecutionTimer;
-import com.amazonaws.http.timers.client.SdkInterruptedException;
-import com.amazonaws.http.timers.request.HttpRequestAbortTaskTracker;
-import com.amazonaws.http.timers.request.HttpRequestTimer;
-import com.amazonaws.internal.AmazonWebServiceRequestAdapter;
-import com.amazonaws.internal.CRC32MismatchException;
-import com.amazonaws.internal.ReleasableInputStream;
-import com.amazonaws.internal.ResettableInputStream;
-import com.amazonaws.internal.SdkBufferedInputStream;
-import com.amazonaws.internal.auth.SignerProviderContext;
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.metrics.RequestMetricCollector;
-import com.amazonaws.retry.RetryPolicyAdapter;
-import com.amazonaws.retry.RetryUtils;
-import com.amazonaws.retry.internal.AuthErrorRetryStrategy;
-import com.amazonaws.retry.internal.AuthRetryParameters;
-import com.amazonaws.retry.v2.RetryPolicy;
-import com.amazonaws.retry.v2.RetryPolicyContext;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.AWSRequestMetrics.Field;
-import com.amazonaws.util.CapacityManager;
-import com.amazonaws.util.CollectionUtils;
-import com.amazonaws.util.CountingInputStream;
-import com.amazonaws.util.DateUtils;
-import com.amazonaws.util.FakeIOException;
-import com.amazonaws.util.ImmutableMapParameter;
-import com.amazonaws.util.MetadataCache;
-import com.amazonaws.util.NullResponseMetadataCache;
-import com.amazonaws.util.ResponseMetadataCache;
-import com.amazonaws.util.RuntimeHttpUtils;
-import com.amazonaws.util.SdkHttpUtils;
-import com.amazonaws.util.UnreliableFilterInputStream;
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Random;
-import java.util.UUID;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpStatus;
-import org.apache.http.StatusLine;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.entity.BufferedHttpEntity;
-import org.apache.http.pool.ConnPoolControl;
-import org.apache.http.pool.PoolStats;
-import org.apache.http.protocol.HttpContext;
-
-@ThreadSafe
-public class AmazonHttpClient {
-    public static final String HEADER_USER_AGENT = "User-Agent";
-    public static final String HEADER_SDK_TRANSACTION_ID = "amz-sdk-invocation-id";
-    public static final String HEADER_SDK_RETRY_INFO = "amz-sdk-retry";
-    /**
-     * Logger for more detailed debugging information, that might not be as useful for end users
-     * (ex: HTTP client configuration, etc).
-     */
-    static final Log log = LogFactory.getLog(AmazonHttpClient.class);
-
-    /**
-     * Logger providing detailed information on requests/responses. Users can enable this logger to
-     * get access to AWS request IDs for responses, individual requests and parameters sent to AWS,
-     * etc.
-     */
-    @SdkInternalApi
-    public static final Log requestLog = LogFactory.getLog("com.amazonaws.request");
-
-    private static final HttpClientFactory<ConnectionManagerAwareHttpClient> httpClientFactory = new
-            ApacheHttpClientFactory();
-    /**
-     * Used for testing via failure injection.
-     */
-    private static UnreliableTestConfig unreliableTestConfig;
-
-    /**
-     * When throttled retries are enabled, each retry attempt will consume this much capacity.
-     * Successful retry attempts will release this capacity back to the pool while failed retries
-     * will not.  Successful initial (non-retry) requests will always release 1 capacity unit to the
-     * pool.
-     */
-    private static final int THROTTLED_RETRY_COST = 5;
-
-    static {
-        // Customers have reported XML parsing issues with the following
-        // JVM versions, which don't occur with more recent versions, so
-        // if we detect any of these, give customers a heads up.
-        // https://bugs.openjdk.java.net/browse/JDK-8028111
-        List<String> problematicJvmVersions = Arrays
-                .asList("1.6.0_06", "1.6.0_13", "1.6.0_17", "1.6.0_65", "1.7.0_45");
-        String jvmVersion = System.getProperty("java.version");
-        if (problematicJvmVersions.contains(jvmVersion)) {
-            log.warn("Detected a possible problem with the current JVM version (" + jvmVersion +
-                     ").  " +
-                     "If you experience XML parsing problems using the SDK, try upgrading to a more recent JVM update.");
-        }
-    }
-
-    private final HttpRequestFactory<HttpRequestBase> httpRequestFactory =
-            new ApacheHttpRequestFactory();
-    /**
-     * Internal client for sending HTTP requests
-     */
-    private ConnectionManagerAwareHttpClient httpClient;
-    /**
-     * Client configuration options, such as proxy httpClientSettings, max retries, etc.
-     */
-    private final ClientConfiguration config;
-
-    private final RetryPolicy retryPolicy;
-
-    /**
-     * Client configuration options, such as proxy httpClientSettings, max retries, etc.
-     */
-    private final HttpClientSettings httpClientSettings;
-    /**
-     * Cache of metadata for recently executed requests for diagnostic purposes
-     */
-    private final MetadataCache responseMetadataCache;
-    /**
-     * Timer to enforce HTTP request timeouts.
-     */
-    private final HttpRequestTimer httpRequestTimer;
-
-    /**
-     * Retry capacity manager, used to manage throttled retry resource
-     */
-    private final CapacityManager retryCapacity;
-
-    /**
-     * Timer to enforce timeouts on the whole execution of the request (request handlers, retries,
-     * backoff strategy, unmarshalling, etc)
-     */
-    private final ClientExecutionTimer clientExecutionTimer;
-    /**
-     * A request metric collector used specifically for this httpClientSettings client; or null if
-     * there is none. This collector, if specified, always takes precedence over the one specified
-     * at the AWS SDK level.
-     *
-     * @see AwsSdkMetrics
-     */
-    private final RequestMetricCollector requestMetricCollector;
-
-    /**
-     * Used to generate UUID's for client transaction id. This gives a higher probability of id
-     * clashes but is more performant then using {@link UUID#randomUUID()} which uses SecureRandom
-     * internally.
-     **/
-    private final Random random = new Random();
-
-    /**
-     * The time difference in seconds between this client and AWS.
-     */
-    private volatile int timeOffset = SDKGlobalTime.getGlobalTimeOffset();
-
-    /**
-     * Constructs a new AWS client using the specified client configuration options (ex: max retry
-     * attempts, proxy httpClientSettings, etc).
-     *
-     * @param config Configuration options specifying how this client will communicate with AWS (ex:
-     *               proxy httpClientSettings, retry count, etc.).
-     */
-    public AmazonHttpClient(ClientConfiguration config) {
-        this(config, null);
-    }
-
-    /**
-     * Constructs a new AWS client using the specified client configuration options (ex: max retry
-     * attempts, proxy httpClientSettings, etc), and request metric collector.
-     *
-     * @param config                 Configuration options specifying how this client will
-     *                               communicate with AWS (ex: proxy httpClientSettings, retry
-     *                               count, etc.).
-     * @param requestMetricCollector client specific request metric collector, which takes
-     *                               precedence over the one at the AWS SDK level; or null if there
-     *                               is none.
-     */
-    public AmazonHttpClient(ClientConfiguration config,
-                            RequestMetricCollector requestMetricCollector) {
-        this(config, requestMetricCollector, false);
-    }
-
-    /**
-     * Constructs a new AWS client using the specified client configuration options (ex: max retry
-     * attempts, proxy httpClientSettings, etc), and request metric collector.
-     *
-     * @param config                 Configuration options specifying how this client will
-     *                               communicate with AWS (ex: proxy httpClientSettings, retry
-     *                               count, etc.).
-     * @param requestMetricCollector client specific request metric collector, which takes
-     *                               precedence over the one at the AWS SDK level; or null if there
-     *                               is none.
-     */
-    public AmazonHttpClient(ClientConfiguration config,
-                            RequestMetricCollector requestMetricCollector,
-                            boolean useBrowserCompatibleHostNameVerifier) {
-        this(config, requestMetricCollector, useBrowserCompatibleHostNameVerifier, false);
-    }
-
-    /**
-     * Constructs a new AWS client using the specified client configuration options (ex: max retry
-     * attempts, proxy httpClientSettings, etc), and request metric collector.
-     *
-     * @param config                           Configuration options specifying how this client will
-     *                                         communicate with AWS (ex: proxy httpClientSettings,
-     *                                         retry count, etc.).
-     * @param requestMetricCollector           client specific request metric collector, which takes
-     *                                         precedence over the one at the AWS SDK level; or null
-     *                                         if there is none.
-     * @param calculateCRC32FromCompressedData The flag indicating whether the CRC32 checksum is
-     *                                         calculated from compressed data or not. It is only
-     *                                         applicable when the header "x-amz-crc32" is set in
-     *                                         the response.
-     */
-    public AmazonHttpClient(ClientConfiguration config,
-                            RequestMetricCollector requestMetricCollector,
-                            boolean useBrowserCompatibleHostNameVerifier,
-                            boolean calculateCRC32FromCompressedData) {
-        this(config,
-             null,
-             requestMetricCollector,
-             useBrowserCompatibleHostNameVerifier,
-             calculateCRC32FromCompressedData);
-    }
-
-    private AmazonHttpClient(ClientConfiguration config,
-                             RetryPolicy retryPolicy,
-                             RequestMetricCollector requestMetricCollector,
-                             boolean useBrowserCompatibleHostNameVerifier,
-                             boolean calculateCRC32FromCompressedData) {
-        this(config,
-             retryPolicy,
-             requestMetricCollector,
-             HttpClientSettings.adapt(config, useBrowserCompatibleHostNameVerifier, calculateCRC32FromCompressedData));
-        this.httpClient = httpClientFactory.create(this.httpClientSettings);
-    }
-
-    /**
-     * Package-protected constructor for unit test purposes.
-     */
-    @SdkTestInternalApi
-    public AmazonHttpClient(ClientConfiguration clientConfig,
-                            ConnectionManagerAwareHttpClient httpClient,
-                            RequestMetricCollector requestMetricCollector) {
-        this(clientConfig,
-             null,
-             requestMetricCollector,
-             HttpClientSettings.adapt(clientConfig, false));
-        this.httpClient = httpClient;
-    }
-
-    private AmazonHttpClient(ClientConfiguration clientConfig,
-                             RetryPolicy retryPolicy,
-                             RequestMetricCollector requestMetricCollector,
-                             HttpClientSettings httpClientSettings) {
-        this.config = clientConfig;
-        this.retryPolicy =
-                retryPolicy == null ? new RetryPolicyAdapter(clientConfig.getRetryPolicy(), clientConfig) : retryPolicy;
-        this.httpClientSettings = httpClientSettings;
-        this.requestMetricCollector = requestMetricCollector;
-        this.responseMetadataCache =
-                clientConfig.getCacheResponseMetadata() ?
-                        new ResponseMetadataCache(clientConfig.getResponseMetadataCacheSize()) :
-                        new NullResponseMetadataCache();
-        this.httpRequestTimer = new HttpRequestTimer();
-        this.clientExecutionTimer = new ClientExecutionTimer();
-
-        // When enabled, total retry capacity is computed based on retry cost
-        // and desired number of retries.
-        int throttledRetryMaxCapacity = clientConfig.useThrottledRetries()
-                ? THROTTLED_RETRY_COST * config.getMaxConsecutiveRetriesBeforeThrottling() : -1;
-        this.retryCapacity = new CapacityManager(throttledRetryMaxCapacity);
-    }
-
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    public static class Builder {
-
-        private ClientConfiguration clientConfig;
-        private RetryPolicy retryPolicy;
-        private RequestMetricCollector requestMetricCollector;
-        private boolean useBrowserCompatibleHostNameVerifier;
-        private boolean calculateCRC32FromCompressedData;
-
-        private Builder() {
-        }
-
-        public Builder clientConfiguration(ClientConfiguration clientConfig) {
-            this.clientConfig = clientConfig;
-            return this;
-        }
-
-        public Builder retryPolicy(RetryPolicy retryPolicy) {
-            this.retryPolicy = retryPolicy;
-            return this;
-        }
-
-        public Builder requestMetricCollector(RequestMetricCollector requestMetricCollector) {
-            this.requestMetricCollector = requestMetricCollector;
-            return this;
-        }
-
-        public Builder useBrowserCompatibleHostNameVerifier(boolean useBrowserCompatibleHostNameVerifier) {
-            this.useBrowserCompatibleHostNameVerifier = useBrowserCompatibleHostNameVerifier;
-            return this;
-        }
-
-        public Builder calculateCRC32FromCompressedData(boolean calculateCRC32FromCompressedData) {
-            this.calculateCRC32FromCompressedData = calculateCRC32FromCompressedData;
-            return this;
-        }
-
-        public AmazonHttpClient build() {
-            return new AmazonHttpClient(clientConfig,
-                                        retryPolicy,
-                                        requestMetricCollector,
-                                        useBrowserCompatibleHostNameVerifier,
-                                        calculateCRC32FromCompressedData);
-        }
-    }
-
-    private static boolean isTemporaryRedirect(org.apache.http.HttpResponse response) {
-        int status = response.getStatusLine().getStatusCode();
-        return status == HttpStatus.SC_TEMPORARY_REDIRECT && response.getHeaders("Location") != null
-               && response.getHeaders("Location").length > 0;
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        this.shutdown();
-        super.finalize();
-    }
-
-    /**
-     * Shuts down this HTTP client object, releasing any resources that might be held open. This is
-     * an optional method, and callers are not expected to call it, but can if they want to
-     * explicitly release any open resources. Once a client has been shutdown, it cannot be used to
-     * make more requests.
-     */
-    public void shutdown() {
-        clientExecutionTimer.shutdown();
-        httpRequestTimer.shutdown();
-        IdleConnectionReaper.removeConnectionManager(httpClient.getHttpClientConnectionManager());
-        httpClient.getHttpClientConnectionManager().shutdown();
-    }
-
-    /**
-     * Used to configure the test conditions for injecting intermittent failures to the content
-     * input stream.
-     *
-     * @param config unreliable test configuration for failure injection; or null to disable such
-     *               test.
-     */
-    static void configUnreliableTestConditions(UnreliableTestConfig config) {
-        unreliableTestConfig = config;
-    }
-
-    /**
-     * Package protected for unit-testing
-     */
-    @SdkTestInternalApi
-    public HttpRequestTimer getHttpRequestTimer() {
-        return this.httpRequestTimer;
-    }
-
-    /**
-     * Package protected for unit-testing
-     */
-    @SdkTestInternalApi
-    public ClientExecutionTimer getClientExecutionTimer() {
-        return this.clientExecutionTimer;
-    }
-
-    /**
-     * Returns additional response metadata for an executed request. Response metadata isn't
-     * considered part of the standard results returned by an operation, so it's accessed instead
-     * through this diagnostic interface. Response metadata is typically used for troubleshooting
-     * issues with AWS support staff when services aren't acting as expected.
-     *
-     * @param request A previously executed AmazonWebServiceRequest object, whose response metadata
-     *                is desired.
-     * @return The response metadata for the specified request, otherwise null if there is no
-     * response metadata available for the request.
-     */
-    public ResponseMetadata getResponseMetadataForRequest(AmazonWebServiceRequest request) {
-        return responseMetadataCache.get(request);
-    }
-
-    /**
-     * Returns the httpClientSettings client specific request metric collector; or null if there is
-     * none.
-     */
-    public RequestMetricCollector getRequestMetricCollector() {
-        return requestMetricCollector;
-    }
-
-    /**
-     * Returns the time difference in seconds between this client and AWS.
-     */
-    public int getTimeOffset() {
-        return timeOffset;
-    }
-
-    /**
-     * Executes the request and returns the result.
-     *
-     * @param request              The AmazonWebServices request to send to the remote server
-     * @param responseHandler      A response handler to accept a successful response from the
-     *                             remote server
-     * @param errorResponseHandler A response handler to accept an unsuccessful response from the
-     *                             remote server
-     * @param executionContext     Additional information about the context of this web service
-     *                             call
-     * @deprecated Use {@link #requestExecutionBuilder()} to configure and execute a HTTP request.
-     */
-    @Deprecated
-    public <T> Response<T> execute(Request<?> request,
-                                   HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
-                                   HttpResponseHandler<AmazonServiceException> errorResponseHandler,
-                                   ExecutionContext executionContext) {
-        HttpResponseHandler<T> adaptedRespHandler = new AwsResponseHandlerAdapter<T>(
-                getNonNullResponseHandler(responseHandler),
-                request,
-                executionContext.getAwsRequestMetrics(),
-                responseMetadataCache);
-        return requestExecutionBuilder()
-                .request(request)
-                .requestConfig(new AmazonWebServiceRequestAdapter(request.getOriginalRequest()))
-                .errorResponseHandler(new AwsErrorResponseHandler(errorResponseHandler, executionContext.getAwsRequestMetrics()))
-                .executionContext(executionContext)
-                .execute(adaptedRespHandler);
-    }
-
-    /**
-     * Ensures the response handler is not null. If it is this method returns a dummy response
-     * handler.
-     *
-     * @return Either original response handler or dummy response handler.
-     */
-    private <T> HttpResponseHandler<T> getNonNullResponseHandler(
-            HttpResponseHandler<T> responseHandler) {
-        if (responseHandler != null) {
-            return responseHandler;
-        } else {
-            // Return a Dummy, No-Op handler
-            return new HttpResponseHandler<T>() {
-
-                @Override
-                public T handle(HttpResponse response) throws Exception {
-                    return null;
-                }
-
-                @Override
-                public boolean needsConnectionLeftOpen() {
-                    return false;
-                }
-            };
-        }
-    }
-
-    /**
-     * @return A builder used to configure and execute a HTTP request.
-     */
-    public RequestExecutionBuilder requestExecutionBuilder() {
-        return new RequestExecutionBuilderImpl();
-    }
-
-    /**
-     * Interface to configure a request execution and execute the request.
-     */
-    public interface RequestExecutionBuilder {
-
-        /**
-         * Fluent setter for {@link Request}
-         *
-         * @param request Request object
-         * @return This builder for method chaining.
-         */
-        RequestExecutionBuilder request(Request<?> request);
-
-        /**
-         * Fluent setter for the error response handler
-         *
-         * @param errorResponseHandler Error response handler
-         * @return This builder for method chaining.
-         */
-        RequestExecutionBuilder errorResponseHandler(
-                HttpResponseHandler<? extends SdkBaseException> errorResponseHandler);
-
-        /**
-         * Fluent setter for the execution context
-         *
-         * @param executionContext Execution context
-         * @return This builder for method chaining.
-         */
-        RequestExecutionBuilder executionContext(ExecutionContext executionContext);
-
-        /**
-         * Fluent setter for {@link RequestConfig}
-         *
-         * @param requestConfig Request config object
-         * @return This builder for method chaining.
-         */
-        RequestExecutionBuilder requestConfig(RequestConfig requestConfig);
-
-        /**
-         * Executes the request with the given configuration.
-         *
-         * @param responseHandler Response handler that outputs the actual result type which is
-         *                        preferred going forward.
-         * @param <Output>        Result type
-         * @return Unmarshalled result type.
-         */
-        <Output> Response<Output> execute(HttpResponseHandler<Output> responseHandler);
-
-        /**
-         * Executes the request with the given configuration; not handling response.
-         *
-         * @return Void response
-         */
-        Response<Void> execute();
-
-    }
-
-    private class RequestExecutionBuilderImpl implements RequestExecutionBuilder {
-
-        private Request<?> request;
-        private RequestConfig requestConfig;
-        private HttpResponseHandler<? extends SdkBaseException> errorResponseHandler;
-        private ExecutionContext executionContext = new ExecutionContext();
-
-        @Override
-        public RequestExecutionBuilder request(Request<?> request) {
-            this.request = request;
-            return this;
-        }
-
-        @Override
-        public RequestExecutionBuilder errorResponseHandler(
-                HttpResponseHandler<? extends SdkBaseException> errorResponseHandler) {
-            this.errorResponseHandler = errorResponseHandler;
-            return this;
-        }
-
-        @Override
-        public RequestExecutionBuilder executionContext(
-                ExecutionContext executionContext) {
-            this.executionContext = executionContext;
-            return this;
-        }
-
-        @Override
-        public RequestExecutionBuilder requestConfig(RequestConfig requestConfig) {
-            this.requestConfig = requestConfig;
-            return this;
-        }
-
-        @Override
-        public <Output> Response<Output> execute(HttpResponseHandler<Output> responseHandler) {
-            RequestConfig config = requestConfig != null ? requestConfig : new AmazonWebServiceRequestAdapter(request.getOriginalRequest());
-            return new RequestExecutor<Output>(request,
-                                               config,
-                                               getNonNullResponseHandler(errorResponseHandler),
-                                               getNonNullResponseHandler(responseHandler),
-                                               executionContext,
-                                               getRequestHandlers()
-            ).execute();
-        }
-
-        @Override
-        public Response<Void> execute() {
-            return execute(null);
-        }
-
-        private List<RequestHandler2> getRequestHandlers() {
-            List<RequestHandler2> requestHandler2s = executionContext.getRequestHandler2s();
-            if (requestHandler2s == null) {
-                return Collections.emptyList();
-            }
-            return requestHandler2s;
-        }
-
-    }
-
-    private class RequestExecutor<Output> {
-        private final Request<?> request;
-        private final RequestConfig requestConfig;
-        private final HttpResponseHandler<? extends SdkBaseException> errorResponseHandler;
-        private final HttpResponseHandler<Output> responseHandler;
-        private final ExecutionContext executionContext;
-        private final List<RequestHandler2> requestHandler2s;
-        private final AWSRequestMetrics awsRequestMetrics;
-
-        private RequestExecutor(Request<?> request, RequestConfig requestConfig,
-                                HttpResponseHandler<? extends SdkBaseException> errorResponseHandler,
-                                HttpResponseHandler<Output> responseHandler,
-                                ExecutionContext executionContext,
-                                List<RequestHandler2> requestHandler2s) {
-            this.request = request;
-            this.requestConfig = requestConfig;
-            this.errorResponseHandler = errorResponseHandler;
-            this.responseHandler = responseHandler;
-            this.executionContext = executionContext;
-            this.requestHandler2s = requestHandler2s;
-            this.awsRequestMetrics = executionContext.getAwsRequestMetrics();
-        }
-
-        /**
-         * Executes the request and returns the result.
-         */
-        private Response<Output> execute() {
-            if (executionContext == null) {
-                throw new SdkClientException(
-                        "Internal SDK Error: No execution context parameter specified.");
-            }
-            try {
-                return executeWithTimer();
-            } catch (InterruptedException ie) {
-                throw handleInterruptedException(ie);
-            } catch (AbortedException ae) {
-                throw handleAbortedException(ae);
-            }
-        }
-
-        /**
-         * Start and end client execution timer around the execution of the request. It's important
-         * that the client execution task is canceled before the InterruptedExecption is handled by
-         * {@link #execute()} so * the interrupt status doesn't leak out to the callers code
-         */
-        private Response<Output> executeWithTimer() throws InterruptedException {
-            ClientExecutionAbortTrackerTask clientExecutionTrackerTask =
-                    clientExecutionTimer.startTimer(getClientExecutionTimeout(requestConfig));
-            try {
-                executionContext.setClientExecutionTrackerTask(clientExecutionTrackerTask);
-                return doExecute();
-            } finally {
-                executionContext.getClientExecutionTrackerTask().cancelTask();
-            }
-        }
-
-        private Response<Output> doExecute() throws InterruptedException {
-            runBeforeRequestHandlers();
-            setSdkTransactionId(request);
-            setUserAgent(request);
-
-            ProgressListener listener = requestConfig.getProgressListener();
-            // add custom headers
-            request.getHeaders().putAll(config.getHeaders());
-            request.getHeaders().putAll(requestConfig.getCustomRequestHeaders());
-            // add custom query parameters
-            mergeQueryParameters(requestConfig.getCustomQueryParameters());
-            Response<Output> response = null;
-            final InputStream origContent = request.getContent();
-            final InputStream toBeClosed = beforeRequest(); // for progress tracking
-            // make "notCloseable", so reset would work with retries
-            final InputStream notCloseable = (toBeClosed == null) ? null
-                    : ReleasableInputStream.wrap(toBeClosed).disableClose();
-            request.setContent(notCloseable);
-            try {
-                publishProgress(listener, ProgressEventType.CLIENT_REQUEST_STARTED_EVENT);
-                response = executeHelper();
-                publishProgress(listener, ProgressEventType.CLIENT_REQUEST_SUCCESS_EVENT);
-                awsRequestMetrics.getTimingInfo().endTiming();
-                afterResponse(response);
-                return response;
-            } catch (AmazonClientException e) {
-                publishProgress(listener, ProgressEventType.CLIENT_REQUEST_FAILED_EVENT);
-
-                // Exceptions generated here will block the rethrow of e.
-                afterError(response, e);
-                throw e;
-            } finally {
-                // Always close so any progress tracking would get the final events propagated.
-                closeQuietly(toBeClosed, log);
-                request.setContent(origContent); // restore the original content
-            }
-        }
-
-        private void runBeforeRequestHandlers() {
-            AWSCredentials credentials = getCredentialsFromContext();
-            request.addHandlerContext(HandlerContextKey.AWS_CREDENTIALS, credentials);
-            // Apply any additional service specific request handlers that need to be run
-            for (RequestHandler2 requestHandler2 : requestHandler2s) {
-                // If the request handler is a type of CredentialsRequestHandler, then set the credentials in the request handler.
-                if (requestHandler2 instanceof CredentialsRequestHandler) {
-                    ((CredentialsRequestHandler) requestHandler2).setCredentials(credentials);
-                }
-                requestHandler2.beforeRequest(request);
-            }
-        }
-
-        /**
-         * Determine if an interrupted exception is caused by the client execution timer
-         * interrupting the current thread or some other task interrupting the thread for another
-         * purpose.
-         *
-         * @return {@link ClientExecutionTimeoutException} if the {@link InterruptedException} was
-         * caused by the {@link ClientExecutionTimer}. Otherwise re-interrupts the current thread
-         * and returns a {@link SdkClientException} wrapping an {@link InterruptedException}
-         */
-        private RuntimeException handleInterruptedException(InterruptedException e) {
-            if (e instanceof SdkInterruptedException) {
-                if (((SdkInterruptedException) e).getResponse() != null) {
-                    ((SdkInterruptedException) e).getResponse().getHttpResponse().getHttpRequest().abort();
-                }
-            }
-            if (executionContext.getClientExecutionTrackerTask().hasTimeoutExpired()) {
-                // Clear the interrupt status
-                Thread.interrupted();
-                return new ClientExecutionTimeoutException();
-            } else {
-                Thread.currentThread().interrupt();
-                return new AbortedException(e);
-            }
-        }
-
-        /**
-         * Determine if an aborted exception is caused by the client execution timer interrupting
-         * the current thread. If so throws {@link ClientExecutionTimeoutException} else throws the
-         * original {@link AbortedException}
-         *
-         * @param ae aborted exception that occurred
-         * @return {@link ClientExecutionTimeoutException} if the {@link AbortedException} was
-         * caused by the {@link ClientExecutionTimer}. Otherwise throws the original {@link
-         * AbortedException}
-         */
-        private RuntimeException handleAbortedException(final AbortedException ae) {
-            if (executionContext.getClientExecutionTrackerTask().hasTimeoutExpired()) {
-                return new ClientExecutionTimeoutException();
-            } else {
-                Thread.currentThread().interrupt();
-                return ae;
-            }
-        }
-
-        /**
-         * Check if the thread has been interrupted. If so throw an {@link InterruptedException}.
-         * Long running tasks should be periodically checked if the current thread has been
-         * interrupted and handle it appropriately
-         *
-         * @throws InterruptedException If thread has been interrupted
-         */
-        private void checkInterrupted() throws InterruptedException {
-            checkInterrupted(null);
-        }
-
-        /**
-         * Check if the thread has been interrupted. If so throw an {@link InterruptedException}.
-         * Long running tasks should be periodically checked if the current thread has been
-         * interrupted and handle it appropriately
-         *
-         * @param response Response to be closed before returning control to the caller to avoid
-         *                 leaking the connection.
-         * @throws InterruptedException If thread has been interrupted
-         */
-        private void checkInterrupted(Response<?> response) throws InterruptedException {
-            if (Thread.interrupted()) {
-                throw new SdkInterruptedException(response);
-            }
-        }
-
-        /**
-         * Merge query parameters into the given request.
-         */
-        private void mergeQueryParameters(Map<String, List<String>> params) {
-            Map<String, List<String>> existingParams = request.getParameters();
-            for (Entry<String, List<String>> param : params.entrySet()) {
-                String pName = param.getKey();
-                List<String> pValues = param.getValue();
-                existingParams.put(pName, CollectionUtils.mergeLists(existingParams.get(pName), pValues));
-            }
-        }
-
-        /**
-         * Publishes the "request content length" event, and returns an input stream, which will be
-         * made mark-and-resettable if possible, for progress tracking purposes.
-         *
-         * @return an input stream, which will be made mark-and-resettable if possible, for progress
-         * tracking purposes; or null if the request doesn't have an input stream
-         */
-        private InputStream beforeRequest() {
-            ProgressListener listener = requestConfig.getProgressListener();
-            reportContentLength(listener);
-            if (request.getContent() == null) {
-                return null;
-            }
-            final InputStream content = monitorStreamProgress(listener,
-                                                              buffer(
-                                                                      makeResettable(
-                                                                              request.getContent())));
-            if (AmazonHttpClient.unreliableTestConfig == null) {
-                return content;
-            }
-            return wrapWithUnreliableStream(content);
-        }
-
-        /**
-         * If content length is present on the request, report it to the progress listener.
-         *
-         * @param listener Listener to notify.
-         */
-        private void reportContentLength(ProgressListener listener) {
-            Map<String, String> headers = request.getHeaders();
-            String contentLengthStr = headers.get("Content-Length");
-            if (contentLengthStr != null) {
-                try {
-                    long contentLength = Long.parseLong(contentLengthStr);
-                    publishRequestContentLength(listener, contentLength);
-                } catch (NumberFormatException e) {
-                    log.warn("Cannot parse the Content-Length header of the request.");
-                }
-            }
-        }
-
-        /**
-         * Make input stream resettable if possible.
-         *
-         * @param content Input stream to make resettable
-         * @return ResettableInputStream if possible otherwise original input stream.
-         */
-        private InputStream makeResettable(InputStream content) {
-            if (!content.markSupported()) {
-                // try to wrap the content input stream to become
-                // mark-and-resettable for signing and retry purposes.
-                if (content instanceof FileInputStream) {
-                    try {
-                        // ResettableInputStream supports mark-and-reset without
-                        // memory buffering
-                        return new ResettableInputStream((FileInputStream) content);
-                    } catch (IOException e) {
-                        if (log.isDebugEnabled()) {
-                            log.debug("For the record; ignore otherwise", e);
-                        }
-                    }
-                }
-            }
-            return content;
-        }
-
-        /**
-         * Buffer input stream if possible.
-         *
-         * @param content Input stream to buffer
-         * @return SdkBufferedInputStream if possible, otherwise original input stream.
-         */
-        private InputStream buffer(InputStream content) {
-            if (!content.markSupported()) {
-                content = new SdkBufferedInputStream(content);
-            }
-            return content;
-        }
-
-        /**
-         * Wrap with a {@link ProgressInputStream} to report request progress to listener.
-         *
-         * @param listener Listener to report to
-         * @param content  Input stream to monitor progress for
-         * @return Wrapped input stream with progress monitoring capabilities.
-         */
-        private InputStream monitorStreamProgress(ProgressListener listener,
-                                                  InputStream content) {
-            return ProgressInputStream.inputStreamForRequest(content, listener);
-        }
-
-        /**
-         * Used only for internal testing purposes. Makes a stream unreliable in certain ways for
-         * fault testing.
-         *
-         * @param content Input stream to make unreliable.
-         * @return UnreliableFilterInputStream
-         */
-        private InputStream wrapWithUnreliableStream(InputStream content) {
-            return new UnreliableFilterInputStream(content,
-                                                   unreliableTestConfig.isFakeIOException())
-                    .withBytesReadBeforeException(
-                            unreliableTestConfig.getBytesReadBeforeException())
-                    .withMaxNumErrors(unreliableTestConfig.getMaxNumErrors())
-                    .withResetIntervalBeforeException(
-                            unreliableTestConfig.getResetIntervalBeforeException());
-        }
-
-
-        private void afterError(Response<?> response,
-                                AmazonClientException e) throws InterruptedException {
-            for (RequestHandler2 handler2 : requestHandler2s) {
-                handler2.afterError(request, response, e);
-                checkInterrupted(response);
-            }
-        }
-
-        private <T> void afterResponse(Response<T> response) throws InterruptedException {
-            for (RequestHandler2 handler2 : requestHandler2s) {
-                handler2.afterResponse(request, response);
-                checkInterrupted(response);
-            }
-        }
-
-        private <T> void beforeAttempt(HandlerBeforeAttemptContext context) throws InterruptedException {
-            for (RequestHandler2 handler2 : requestHandler2s) {
-                handler2.beforeAttempt(context);
-                checkInterrupted();
-            }
-        }
-
-        private <T> void afterAttempt(HandlerAfterAttemptContext context) throws InterruptedException {
-            for (RequestHandler2 handler2 : requestHandler2s) {
-                handler2.afterAttempt(context);
-                checkInterrupted(context.getResponse());
-            }
-        }
-
-        /**
-         * Internal method to execute the HTTP method given.
-         */
-        private Response<Output> executeHelper() throws InterruptedException {
-        /*
-         * add the service endpoint to the logs. You can infer service name from service endpoint
-         */
-            awsRequestMetrics
-                    .addPropertyWith(Field.RequestType, requestConfig.getRequestType())
-                    .addPropertyWith(Field.ServiceName, request.getServiceName())
-                    .addPropertyWith(Field.ServiceEndpoint, request.getEndpoint());
-            // Make a copy of the original request params and headers so that we can
-            // permute it in this loop and start over with the original every time.
-            final Map<String, List<String>> originalParameters = new LinkedHashMap<String, List<String>>(request.getParameters());
-            final Map<String, String> originalHeaders = new HashMap<String, String>(request.getHeaders());
-            // Always mark the input stream before execution.
-            final ExecOneRequestParams execOneParams = new ExecOneRequestParams();
-            final InputStream originalContent = request.getContent();
-            if (originalContent != null && originalContent.markSupported()
-                && !(originalContent instanceof BufferedInputStream)) {
-                // Mark only once for non-BufferedInputStream
-                final int readLimit = requestConfig.getRequestClientOptions().getReadLimit();
-                originalContent.mark(readLimit);
-            }
-            while (true) {
-                checkInterrupted();
-                if (originalContent instanceof BufferedInputStream && originalContent.markSupported()) {
-                    // Mark everytime for BufferedInputStream, since the marker could have been invalidated
-                    final int readLimit = requestConfig.getRequestClientOptions().getReadLimit();
-                    originalContent.mark(readLimit);
-                }
-                execOneParams.initPerRetry();
-                if (execOneParams.redirectedURI != null) {
-                /*
-                 * [scheme:][//authority][path][?query][#fragment]
-                 */
-                    String scheme = execOneParams.redirectedURI.getScheme();
-                    String beforeAuthority = scheme == null ? "" : scheme + "://";
-                    String authority = execOneParams.redirectedURI.getAuthority();
-                    String path = execOneParams.redirectedURI.getPath();
-
-                    request.setEndpoint(URI.create(beforeAuthority + authority));
-                    request.setResourcePath(SdkHttpUtils.urlEncode(path, true));
-                }
-                if (execOneParams.authRetryParam != null) {
-                    request.setEndpoint(execOneParams.authRetryParam.getEndpointForRetry());
-                }
-                awsRequestMetrics.setCounter(Field.RequestCount, execOneParams.requestCount);
-                if (execOneParams.isRetry()) {
-                    request.setParameters(originalParameters);
-                    request.setHeaders(originalHeaders);
-                    request.setContent(originalContent);
-                }
-
-                Response<Output> response = null;
-                Exception savedException = null;
-                try {
-                    HandlerBeforeAttemptContext beforeAttemptContext = HandlerBeforeAttemptContext.builder()
-                            .withRequest(request)
-                            .build();
-
-                    beforeAttempt(beforeAttemptContext);
-                    response = executeOneRequest(execOneParams);
-                    savedException = execOneParams.retriedException;
-
-                    if (response != null) {
-                        return response;
-                    }
-                } catch (IOException ioe) {
-                    savedException = ioe;
-                    handleRetryableException(execOneParams, ioe);
-                } catch (InterruptedException ie) {
-                    savedException = ie;
-                    throw ie;
-                } catch (RuntimeException e) {
-                    savedException = e;
-                    throw lastReset(captureExceptionMetrics(e));
-                } catch (Error e) {
-                    throw lastReset(captureExceptionMetrics(e));
-                } finally {
-                /*
-                 * Some response handlers need to manually manage the HTTP connection and will take
-                 * care of releasing the connection on their own, but if this response handler
-                 * doesn't need the connection left open, we go ahead and release the it to free up
-                 * resources.
-                 */
-                    if (!execOneParams.leaveHttpConnectionOpen) {
-                        if (execOneParams.apacheResponse != null) {
-                            HttpEntity entity = execOneParams.apacheResponse.getEntity();
-                            if (entity != null) {
-                                try {
-                                    closeQuietly(entity.getContent(), log);
-                                } catch (IOException e) {
-                                    log.warn("Cannot close the response content.", e);
-                                }
-                            }
-                        }
-                    }
-
-                    HandlerAfterAttemptContext afterAttemptContext = HandlerAfterAttemptContext.builder()
-                            .withRequest(request)
-                            .withResponse(response)
-                            .withException(savedException)
-                            .build();
-
-                    /*
-                     * Exceptions generated here will replace ones rethrown in catch-blocks
-                     * above or thrown in the original try-block.
-                     */
-                    afterAttempt(afterAttemptContext);
-                }
-            } /* end while (true) */
-        }
-
-        private void handleRetryableException(ExecOneRequestParams execOneParams, Exception e) {
-            captureExceptionMetrics(e);
-            awsRequestMetrics.addProperty(Field.AWSRequestID, null);
-            SdkClientException sdkClientException;
-            if (!(e instanceof SdkClientException)) {
-                sdkClientException = new SdkClientException(
-                        "Unable to execute HTTP request: " + e.getMessage(), e);
-            } else {
-                sdkClientException = (SdkClientException) e;
-            }
-            boolean willRetry = shouldRetry(execOneParams, sdkClientException);
-            if (log.isTraceEnabled()) {
-                log.trace(sdkClientException.getMessage() + (willRetry ? " Request will be retried." : ""), e);
-            } else if (log.isDebugEnabled()) {
-                log.trace(sdkClientException.getMessage() + (willRetry ? " Request will be retried." : ""));
-            }
-            if (!willRetry) {
-                throw lastReset(sdkClientException);
-            }
-            // Cache the retryable exception
-            execOneParams.retriedException = sdkClientException;
-        }
-
-        /**
-         * Used to perform a last reset on the content input stream (if mark-supported); this is so
-         * that, for backward compatibility reason, any "blind" retry (ie without calling reset) by
-         * user of this library with the same input stream (such as ByteArrayInputStream) could
-         * still succeed.
-         *
-         * @param t the failure
-         * @return the failure as given
-         */
-        private <T extends Throwable> T lastReset(final T t) {
-            try {
-                InputStream content = request.getContent();
-                if (content != null) {
-                    if (content.markSupported()) {
-                        content.reset();
-                    }
-                }
-            } catch (Exception ex) {
-                log.debug("FYI: failed to reset content inputstream before throwing up", ex);
-            }
-            return t;
-        }
-
-        /**
-         * Returns the credentials from the execution if exists. Else returns null.
-         */
-        private AWSCredentials getCredentialsFromContext() {
-            final AWSCredentialsProvider credentialsProvider = executionContext.getCredentialsProvider();
-
-            AWSCredentials credentials = null;
-            if (credentialsProvider != null) {
-                awsRequestMetrics.startEvent(Field.CredentialsRequestTime);
-                try {
-                    credentials = credentialsProvider.getCredentials();
-                } finally {
-                    awsRequestMetrics.endEvent(Field.CredentialsRequestTime);
-                }
-            }
-            return credentials;
-        }
-
-        /**
-         * Returns the response from executing one httpClientSettings request; or null for retry.
-         */
-        private Response<Output> executeOneRequest(ExecOneRequestParams execOneParams)
-                throws IOException, InterruptedException {
-
-            if (execOneParams.isRetry()) {
-                resetRequestInputStream(request);
-            }
-            checkInterrupted();
-            if (requestLog.isDebugEnabled()) {
-                requestLog.debug((execOneParams.isRetry() ? "Retrying " : "Sending ") + "Request: " + request);
-            }
-            final AWSCredentials credentials = getCredentialsFromContext();
-            final ProgressListener listener = requestConfig.getProgressListener();
-
-            if (execOneParams.isRetry()) {
-                pauseBeforeRetry(execOneParams, listener);
-            }
-            updateRetryHeaderInfo(request, execOneParams);
-
-            // Sign the request if a signer was provided
-            execOneParams.newSigner(request, executionContext);
-            if (execOneParams.signer != null &&
-                (credentials != null || execOneParams.signer instanceof CanHandleNullCredentials)) {
-                awsRequestMetrics.startEvent(Field.RequestSigningTime);
-                try {
-                    if (timeOffset != 0) {
-                        // Always use the client level timeOffset if it was
-                        // non-zero; Otherwise, we respect the timeOffset in the
-                        // request, which could have been externally configured (at
-                        // least for the 1st non-retry request).
-                        //
-                        // For retry due to clock skew, the timeOffset in the
-                        // request used for the retry is assumed to have been
-                        // adjusted when execution reaches here.
-                        request.setTimeOffset(timeOffset);
-                    }
-                    execOneParams.signer.sign(request, credentials);
-                } finally {
-                    awsRequestMetrics.endEvent(Field.RequestSigningTime);
-                }
-            }
-
-            checkInterrupted();
-            execOneParams.newApacheRequest(httpRequestFactory, request, httpClientSettings);
-
-            captureConnectionPoolMetrics();
-
-            final HttpClientContext localRequestContext =
-                    ApacheUtils.newClientContext(httpClientSettings, ImmutableMapParameter.of
-                            (AWSRequestMetrics.SIMPLE_NAME, awsRequestMetrics));
-
-            execOneParams.resetBeforeHttpRequest();
-            publishProgress(listener, ProgressEventType.HTTP_REQUEST_STARTED_EVENT);
-            awsRequestMetrics.startEvent(Field.HttpRequestTime);
-            awsRequestMetrics.setCounter(Field.RetryCapacityConsumed, retryCapacity.consumedCapacity());
-
-            /////////// Send HTTP request ////////////
-            executionContext.getClientExecutionTrackerTask().setCurrentHttpRequest(execOneParams.apacheRequest);
-            final HttpRequestAbortTaskTracker requestAbortTaskTracker = httpRequestTimer
-                    .startTimer(execOneParams.apacheRequest, getRequestTimeout(requestConfig));
-
-            try {
-                execOneParams.apacheResponse = httpClient.execute(execOneParams.apacheRequest, localRequestContext);
-                if (shouldBufferHttpEntity(responseHandler.needsConnectionLeftOpen(),
-                                           executionContext,
-                                           execOneParams,
-                                           requestAbortTaskTracker)) {
-                    execOneParams.apacheResponse
-                            .setEntity(new BufferedHttpEntity(
-                                    execOneParams.apacheResponse.getEntity()));
-                }
-            } catch (IOException ioe) {
-                // Client execution timeouts take precedence as it's not retryable
-                if (executionContext.getClientExecutionTrackerTask().hasTimeoutExpired()) {
-                    throw new InterruptedException();
-                } else if (requestAbortTaskTracker.httpRequestAborted()) {
-                    throw new HttpRequestTimeoutException(ioe);
-                } else {
-                    throw ioe;
-                }
-            } finally {
-                requestAbortTaskTracker.cancelTask();
-                awsRequestMetrics.endEvent(Field.HttpRequestTime);
-            }
-
-            publishProgress(listener, ProgressEventType.HTTP_REQUEST_COMPLETED_EVENT);
-            final StatusLine statusLine = execOneParams.apacheResponse.getStatusLine();
-            final int statusCode = statusLine == null ? -1 : statusLine.getStatusCode();
-            if (ApacheUtils.isRequestSuccessful(execOneParams.apacheResponse)) {
-                awsRequestMetrics.addProperty(Field.StatusCode, statusCode);
-            /*
-             * If we get back any 2xx status code, then we know we should treat the service call as
-             * successful.
-             */
-                execOneParams.leaveHttpConnectionOpen = responseHandler.needsConnectionLeftOpen();
-                HttpResponse httpResponse = ApacheUtils.createResponse(request, execOneParams.apacheRequest, execOneParams.apacheResponse, localRequestContext);
-                Output response = handleResponse(httpResponse);
-
-            /*
-             * If this was a successful retry attempt we'll release the full retry capacity that
-             * the attempt originally consumed.  If this was a successful initial request
-             * we return a lesser amount.
-             */
-                if (execOneParams.isRetry() && executionContext.retryCapacityConsumed()) {
-                    retryCapacity.release(THROTTLED_RETRY_COST);
-                } else {
-                    retryCapacity.release();
-                }
-                return new Response<Output>(response, httpResponse);
-            }
-            if (isTemporaryRedirect(execOneParams.apacheResponse)) {
-            /*
-             * S3 sends 307 Temporary Redirects if you try to delete an EU bucket from the US
-             * endpoint. If we get a 307, we'll point the HTTP method to the redirected location,
-             * and let the next retry deliver the request to the right location.
-             */
-                Header[] locationHeaders = execOneParams.apacheResponse.getHeaders("location");
-                String redirectedLocation = locationHeaders[0].getValue();
-                if (log.isDebugEnabled()) {
-                    log.debug("Redirecting to: " + redirectedLocation);
-                }
-                execOneParams.redirectedURI = URI.create(redirectedLocation);
-                awsRequestMetrics.addPropertyWith(Field.StatusCode, statusCode)
-                        .addPropertyWith(Field.RedirectLocation, redirectedLocation)
-                        .addPropertyWith(Field.AWSRequestID, null);
-                return null; // => retry
-            }
-            execOneParams.leaveHttpConnectionOpen = errorResponseHandler.needsConnectionLeftOpen();
-            final SdkBaseException exception = handleErrorResponse(execOneParams.apacheRequest,
-                                                             execOneParams.apacheResponse,
-                                                             localRequestContext);
-
-            /*
-             * If the exception is related to Clock skew,
-             * then update the client global time offset
-             * irrespective of retry logic
-             */
-            if (RetryUtils.isClockSkewError(exception)) {
-                int clockSkew = parseClockSkewOffset(execOneParams.apacheResponse, exception);
-                SDKGlobalTime.setGlobalTimeOffset(timeOffset = clockSkew);
-                request.setTimeOffset(timeOffset); // adjust time offset for the retry
-            }
-
-
-            // Check whether we should internally retry the auth error
-            execOneParams.authRetryParam = null;
-            AuthErrorRetryStrategy authRetry = executionContext.getAuthErrorRetryStrategy();
-            if (authRetry != null && exception instanceof AmazonServiceException) {
-                HttpResponse httpResponse = ApacheUtils.createResponse(request, execOneParams.apacheRequest, execOneParams.apacheResponse, localRequestContext);
-                execOneParams.authRetryParam = authRetry
-                        .shouldRetryWithAuthParam(request, httpResponse, (AmazonServiceException) exception);
-            }
-            if (execOneParams.authRetryParam == null && !shouldRetry(execOneParams, exception)) {
-                throw exception;
-            }
-            // Comment out for now. Ref: CR2662349
-            // Preserve the cause of retry before retrying
-            // awsRequestMetrics.addProperty(RetryCause, ase);
-            if (RetryUtils.isThrottlingException(exception)) {
-                awsRequestMetrics.incrementCounterWith(Field.ThrottleException)
-                        .addProperty(Field.ThrottleException, exception);
-            }
-            // Cache the retryable exception
-            execOneParams.retriedException = exception;
-
-            return null; // => retry
-        }
-
-        /**
-         * Reset the input stream of the request before a retry.
-         *
-         * @param request Request containing input stream to reset
-         * @throws ResetException If Input Stream can't be reset which means the request can't be
-         *                        retried
-         */
-        private void resetRequestInputStream(final Request<?> request) throws ResetException {
-            InputStream requestInputStream = request.getContent();
-            if (requestInputStream != null) {
-                if (requestInputStream.markSupported()) {
-                    try {
-                        requestInputStream.reset();
-                    } catch (IOException ex) {
-                        throw new ResetException("Failed to reset the request input stream", ex);
-                    }
-                }
-            }
-        }
-
-        /**
-         * @return True if the {@link HttpEntity} should be wrapped in a {@link BufferedHttpEntity}
-         */
-        private boolean shouldBufferHttpEntity(final boolean needsConnectionLeftOpen,
-                                               final ExecutionContext execContext,
-                                               ExecOneRequestParams execParams,
-                                               final HttpRequestAbortTaskTracker requestAbortTaskTracker) {
-            return (execContext.getClientExecutionTrackerTask().isEnabled() ||
-                    requestAbortTaskTracker.isEnabled())
-                   && !needsConnectionLeftOpen && execParams.apacheResponse.getEntity() != null;
-        }
-
-
-        /**
-         * Captures the connection pool metrics.
-         */
-        private void captureConnectionPoolMetrics() {
-            if (awsRequestMetrics.isEnabled() &&
-                httpClient.getHttpClientConnectionManager() instanceof
-                        ConnPoolControl<?>) {
-                final PoolStats stats = ((ConnPoolControl<?>) httpClient
-                        .getHttpClientConnectionManager()).getTotalStats();
-
-                awsRequestMetrics
-                        .withCounter(HttpClientPoolAvailableCount, stats.getAvailable())
-                        .withCounter(HttpClientPoolLeasedCount, stats.getLeased())
-                        .withCounter(HttpClientPoolPendingCount, stats.getPending());
-            }
-
-        }
-
-        /**
-         * Capture the metrics for the given throwable.
-         */
-        private <T extends Throwable> T captureExceptionMetrics(T t) {
-            awsRequestMetrics.incrementCounterWith(Field.Exception)
-                    .addProperty(Field.Exception, t);
-            if (t instanceof AmazonServiceException) {
-                AmazonServiceException ase = (AmazonServiceException) t;
-                if (RetryUtils.isThrottlingException(ase)) {
-                    awsRequestMetrics.incrementCounterWith(Field.ThrottleException)
-                            .addProperty(Field.ThrottleException, ase);
-                }
-            }
-            return t;
-        }
-
-        /**
-         * Create a client side identifier that will be sent with the initial request and each
-         * retry.
-         */
-        private void setSdkTransactionId(Request<?> request) {
-            request.addHeader(HEADER_SDK_TRANSACTION_ID,
-                              new UUID(random.nextLong(), random.nextLong()).toString());
-        }
-
-        /**
-         * Sets a User-Agent for the specified request, taking into account any custom data.
-         */
-        private void setUserAgent(Request<?> request) {
-            RequestClientOptions opts = requestConfig.getRequestClientOptions();
-            if (opts != null) {
-                request.addHeader(HEADER_USER_AGENT, RuntimeHttpUtils
-                        .getUserAgent(config, opts.getClientMarker(Marker.USER_AGENT)));
-            } else {
-                request.addHeader(HEADER_USER_AGENT, RuntimeHttpUtils.getUserAgent(config, null));
-            }
-        }
-
-        /**
-         * Adds Retry information to the {@link #HEADER_SDK_RETRY_INFO} header. Used for analysis of
-         * retry policy.
-         *
-         * @param request              Request to add header to
-         * @param execOneRequestParams Request context containing retry information
-         */
-        private void updateRetryHeaderInfo(Request<?> request,
-                                           ExecOneRequestParams execOneRequestParams) {
-            int availableRetryCapacity = retryCapacity.availableCapacity();
-
-            String headerValue = String.format("%s/%s/%s",
-                                               execOneRequestParams.requestCount - 1,
-                                               execOneRequestParams.lastBackoffDelay,
-                                               availableRetryCapacity >= 0 ?
-                                                       availableRetryCapacity : "");
-
-            request.addHeader(HEADER_SDK_RETRY_INFO, headerValue);
-        }
-
-        /**
-         * Returns true if a failed request should be retried.
-         *
-         * @param params    Params for the individual request being executed.
-         * @param exception The client/service exception from the failed request.
-         * @return True if the failed request should be retried.
-         */
-        private boolean shouldRetry(ExecOneRequestParams params, SdkBaseException exception) {
-            final int retriesAttempted = params.requestCount - 1;
-            final HttpRequestBase method = params.apacheRequest;
-
-            // Never retry on requests containing non-repeatable entity
-            if (method instanceof HttpEntityEnclosingRequest) {
-                HttpEntity entity = ((HttpEntityEnclosingRequest) method).getEntity();
-                if (entity != null && !entity.isRepeatable()) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("Entity not repeatable");
-                    }
-                    return false;
-                }
-            }
-
-            // Do not use retry capacity for throttling exceptions
-            if (!RetryUtils.isThrottlingException(exception)) {
-                // See if we have enough available retry capacity to be able to execute
-                // this retry attempt.
-                if (!retryCapacity.acquire(THROTTLED_RETRY_COST)) {
-                    awsRequestMetrics.incrementCounter(ThrottledRetryCount);
-                    return false;
-                }
-                executionContext.markRetryCapacityConsumed();
-            }
-
-            RetryPolicyContext context = RetryPolicyContext.builder()
-                    .request(request)
-                    .originalRequest(requestConfig.getOriginalRequest())
-                    .exception(exception)
-                    .retriesAttempted(retriesAttempted)
-                    .httpStatusCode(params.getStatusCode())
-                    .build();
-            // Finally, pass all the context information to the RetryCondition and let it
-            // decide whether it should be retried.
-            if (!retryPolicy.shouldRetry(context)) {
-                // If the retry policy fails we immediately return consumed capacity to the pool.
-                if (executionContext.retryCapacityConsumed()) {
-                    retryCapacity.release(THROTTLED_RETRY_COST);
-                }
-                return false;
-            }
-
-            return true;
-        }
-
-        /**
-         * Handles a successful response from a service call by unmarshalling the results using the
-         * specified response handler.
-         *
-         * @return The contents of the response, unmarshalled using the specified response handler.
-         * @throws IOException If any problems were encountered reading the response contents from
-         *                     the HTTP method object.
-         */
-        @SuppressWarnings("deprecation")
-        private Output handleResponse(HttpResponse httpResponse) throws IOException,
-                                                                        InterruptedException {
-            ProgressListener listener = requestConfig.getProgressListener();
-            try {
-            /*
-             * Apply the byte counting stream wrapper if the legacy runtime profiling is enabled.
-             */
-                CountingInputStream countingInputStream = null;
-                InputStream is = httpResponse.getContent();
-                if (is != null) {
-                    if (System.getProperty(PROFILING_SYSTEM_PROPERTY) != null) {
-                        is = countingInputStream = new CountingInputStream(is);
-                        httpResponse.setContent(is);
-                    }
-                    httpResponse.setContent(ProgressInputStream.inputStreamForResponse(is, listener));
-                }
-                Map<String, String> headers = httpResponse.getHeaders();
-                String s = headers.get("Content-Length");
-                if (s != null) {
-                    try {
-                        long contentLength = Long.parseLong(s);
-                        publishResponseContentLength(listener, contentLength);
-                    } catch (NumberFormatException e) {
-                        log.warn("Cannot parse the Content-Length header of the response.");
-                    }
-                }
-
-                Output awsResponse;
-                awsRequestMetrics.startEvent(Field.ResponseProcessingTime);
-                publishProgress(listener, ProgressEventType.HTTP_RESPONSE_STARTED_EVENT);
-                try {
-                    awsResponse = responseHandler
-                            .handle(beforeUnmarshalling(httpResponse));
-                } finally {
-                    awsRequestMetrics.endEvent(Field.ResponseProcessingTime);
-                }
-                publishProgress(listener, ProgressEventType.HTTP_RESPONSE_COMPLETED_EVENT);
-
-                if (countingInputStream != null) {
-                    awsRequestMetrics
-                            .setCounter(Field.BytesProcessed, countingInputStream.getByteCount());
-                }
-                return awsResponse;
-            } catch (CRC32MismatchException e) {
-                throw e;
-            } catch (IOException e) {
-                throw e;
-            } catch (AmazonClientException e) {
-                throw e; // simply rethrow rather than further wrapping it
-            } catch (InterruptedException e) {
-                throw e;
-            } catch (Exception e) {
-                String errorMessage =
-                        "Unable to unmarshall response (" + e.getMessage() + "). Response Code: "
-                        + httpResponse.getStatusCode() + ", Response Text: " +
-                        httpResponse.getStatusText();
-                throw new SdkClientException(errorMessage, e);
-            }
-        }
-
-        /**
-         * Run {@link RequestHandler2#beforeUnmarshalling(Request, HttpResponse)} callback
-         *
-         * @param origHttpResponse Original {@link HttpResponse}
-         * @return {@link HttpResponse} object to pass to unmarshaller. May have been modified or
-         * replaced by the request handlers
-         */
-        private HttpResponse beforeUnmarshalling(HttpResponse origHttpResponse) {
-            HttpResponse toReturn = origHttpResponse;
-            for (RequestHandler2 requestHandler : requestHandler2s) {
-                toReturn = requestHandler.beforeUnmarshalling(request, toReturn);
-            }
-            return toReturn;
-        }
-
-        /**
-         * Responsible for handling an error response, including unmarshalling the error response
-         * into the most specific exception type possible, and throwing the exception.
-         *
-         * @param method The HTTP method containing the actual response content.
-         * @throws IOException If any problems are encountering reading the error response.
-         */
-        private SdkBaseException handleErrorResponse(HttpRequestBase method,
-                                                           final org.apache.http.HttpResponse apacheHttpResponse,
-                                                           final HttpContext context)
-                throws IOException, InterruptedException {
-            final StatusLine statusLine = apacheHttpResponse.getStatusLine();
-            final int statusCode;
-            final String reasonPhrase;
-            if (statusLine == null) {
-                statusCode = -1;
-                reasonPhrase = null;
-            } else {
-                statusCode = statusLine.getStatusCode();
-                reasonPhrase = statusLine.getReasonPhrase();
-            }
-            HttpResponse response = ApacheUtils.createResponse(request, method, apacheHttpResponse, context);
-            SdkBaseException exception;
-            try {
-                exception = errorResponseHandler.handle(response);
-                if (requestLog.isDebugEnabled()) {
-                    requestLog.debug("Received error response: " + exception);
-                }
-            } catch (InterruptedException e) {
-                throw e;
-            } catch (Exception e) {
-                if (e instanceof IOException) {
-                    throw (IOException) e;
-                } else {
-                    String errorMessage = "Unable to unmarshall error response (" + e.getMessage() +
-                                          "). Response Code: "
-                                          + (statusLine == null ? "None" : statusCode) +
-                                          ", Response Text: " + reasonPhrase;
-                    throw new SdkClientException(errorMessage, e);
-                }
-            }
-
-            exception.fillInStackTrace();
-            return exception;
-        }
-
-        /**
-         * Pause before the next retry and record metrics around retry behavior.
-         */
-        private void pauseBeforeRetry(ExecOneRequestParams execOneParams,
-                                      final ProgressListener listener) throws InterruptedException {
-            publishProgress(listener, ProgressEventType.CLIENT_REQUEST_RETRY_EVENT);
-            // Notify the progress listener of the retry
-            awsRequestMetrics.startEvent(Field.RetryPauseTime);
-            try {
-                doPauseBeforeRetry(execOneParams);
-            } finally {
-                awsRequestMetrics.endEvent(Field.RetryPauseTime);
-            }
-        }
-
-        /**
-         * Sleep for a period of time on failed request to avoid flooding a service with retries.
-         */
-        private void doPauseBeforeRetry(ExecOneRequestParams execOneParams) throws InterruptedException {
-            final int retriesAttempted = execOneParams.requestCount - 2;
-            RetryPolicyContext context = RetryPolicyContext.builder()
-                    .request(request)
-                    .originalRequest(requestConfig.getOriginalRequest())
-                    .retriesAttempted(retriesAttempted)
-                    .exception(execOneParams.retriedException)
-                    .build();
-            // don't pause if the retry was not due to a redirection (I.E. when retried exception is null)
-            if (context.exception() != null) {
-                long delay = retryPolicy.computeDelayBeforeNextRetry(context);
-                execOneParams.lastBackoffDelay = delay;
-
-                if (log.isDebugEnabled()) {
-                    log.debug("Retriable error detected, " + "will retry in " + delay +
-                              "ms, attempt number: " + retriesAttempted);
-                }
-                Thread.sleep(delay);
-            }
-        }
-
-        // SWF: Signature not yet current: 20140819T173921Z is still later than 20140819T173829Z
-        // (20140819T173329Z + 5 min.)
-
-        /**
-         * Returns date string from the exception message body in form of yyyyMMdd'T'HHmmss'Z' We
-         * needed to extract date from the message body because SQS is the only service that does
-         * not provide date header in the response. Example, when device time is behind than the
-         * server time than we get a string that looks something like this: "Signature expired:
-         * 20130401T030113Z is now earlier than 20130401T034613Z (20130401T040113Z - 15 min.)"
-         *
-         * @param body The message from where the server time is being extracted
-         * @return Return datetime in string format (yyyyMMdd'T'HHmmss'Z')
-         */
-        private String getServerDateFromException(String body) {
-            final int startPos = body.indexOf("(");
-            int endPos = body.indexOf(" + ");
-            if (endPos == -1) {
-                endPos = body.indexOf(" - ");
-            }
-            return endPos == -1 ? null : body.substring(startPos + 1, endPos);
-        }
-
-        /**
-         * Returns the difference between the client's clock time and the service clock time in unit
-         * of seconds.
-         */
-        private int parseClockSkewOffset(org.apache.http.HttpResponse response,
-                                         SdkBaseException exception) {
-            final long currentTimeMilli = System.currentTimeMillis();
-            Date serverDate;
-            String serverDateStr = null;
-            Header[] responseDateHeader = response.getHeaders("Date");
-
-            try {
-                if (responseDateHeader.length == 0) {
-                    // SQS doesn't return Date header
-                    final String errmsg = exception.getMessage();
-                    serverDateStr = getServerDateFromException(errmsg);
-                    if (serverDateStr == null) {
-                        log.warn("Unable to parse clock skew offset from errmsg: " + errmsg);
-                        return 0;
-                    }
-                    serverDate = DateUtils.parseCompressedISO8601Date(serverDateStr);
-                } else {
-                    serverDateStr = responseDateHeader[0].getValue();
-                    serverDate = DateUtils.parseRFC822Date(serverDateStr);
-                }
-            } catch (RuntimeException e) {
-                log.warn("Unable to parse clock skew offset from response: " + serverDateStr, e);
-                return 0;
-            }
-
-            long diff = currentTimeMilli - serverDate.getTime();
-            return (int) (diff / 1000);
-        }
-
-        /**
-         * Gets the correct request timeout taking into account precedence of the configuration in
-         * {@link AmazonWebServiceRequest} versus {@link ClientConfiguration}
-         *
-         * @param requestConfig Current request configuration
-         * @return Request timeout value or 0 if none is set
-         */
-        private int getRequestTimeout(RequestConfig requestConfig) {
-            if (requestConfig.getRequestTimeout() != null) {
-                return requestConfig.getRequestTimeout();
-            } else {
-                return config.getRequestTimeout();
-            }
-        }
-
-        /**
-         * Gets the correct client execution timeout taking into account precedence of the
-         * configuration in {@link AmazonWebServiceRequest} versus {@link ClientConfiguration}
-         *
-         * @param requestConfig Current request configuration
-         * @return Client Execution timeout value or 0 if none is set
-         */
-        private int getClientExecutionTimeout(RequestConfig requestConfig) {
-            if (requestConfig.getClientExecutionTimeout() != null) {
-                return requestConfig.getClientExecutionTimeout();
-            } else {
-                return config.getClientExecutionTimeout();
-            }
-        }
-
-        /**
-         * Stateful parameters that are used for executing a single httpClientSettings request.
-         */
-        private class ExecOneRequestParams {
-            int requestCount; // monotonic increasing
-            /**
-             * Last delay between retries
-             */
-            long lastBackoffDelay = 0;
-            SdkBaseException retriedException; // last retryable exception
-            HttpRequestBase apacheRequest;
-            org.apache.http.HttpResponse apacheResponse;
-            URI redirectedURI;
-            AuthRetryParameters authRetryParam;
-            /*
-             * Depending on which response handler we end up choosing to handle the HTTP response, it
-             * might require us to leave the underlying HTTP connection open, depending on whether or
-             * not it reads the complete HTTP response stream from the HTTP connection, or if delays
-             * reading any of the content until after a response is returned to the caller.
-             */
-            boolean leaveHttpConnectionOpen;
-            private Signer signer; // cached
-            private URI signerURI;
-
-            boolean isRetry() {
-                return requestCount > 1 || redirectedURI != null || authRetryParam != null;
-            }
-
-            void initPerRetry() {
-                requestCount++;
-                apacheRequest = null;
-                apacheResponse = null;
-                leaveHttpConnectionOpen = false;
-            }
-
-            void newSigner(final Request<?> request, final ExecutionContext execContext) {
-                final SignerProviderContext.Builder signerProviderContext = SignerProviderContext
-                        .builder()
-                        .withRequest(request)
-                        .withRequestConfig(requestConfig);
-                if (authRetryParam != null) {
-                    signerURI = authRetryParam.getEndpointForRetry();
-                    signer = authRetryParam.getSignerForRetry();
-                    // Push the local signer override back to the execution context
-                    execContext.setSigner(signer);
-                } else if (redirectedURI != null && !redirectedURI.equals(signerURI)) {
-                    signerURI = redirectedURI;
-                    signer = execContext.getSigner(signerProviderContext
-                                                           .withUri(signerURI)
-                                                           .withIsRedirect(true)
-                                                           .build());
-                } else if (signer == null) {
-                    signerURI = request.getEndpoint();
-                    signer = execContext
-                            .getSigner(signerProviderContext.withUri(signerURI).build());
-                }
-            }
-
-            /**
-             * @throws FakeIOException thrown only during test simulation
-             */
-            HttpRequestBase newApacheRequest(
-                    final HttpRequestFactory<HttpRequestBase> httpRequestFactory,
-                    final Request<?> request,
-                    final HttpClientSettings options) throws IOException {
-
-                apacheRequest = httpRequestFactory.create(request, options);
-                if (redirectedURI != null) {
-                    apacheRequest.setURI(redirectedURI);
-                }
-                return apacheRequest;
-            }
-
-            void resetBeforeHttpRequest() {
-                retriedException = null;
-                authRetryParam = null;
-                redirectedURI = null;
-            }
-
-            private Integer getStatusCode() {
-                if (apacheResponse == null || apacheResponse.getStatusLine() == null) {
-                    return null;
-                }
-                return apacheResponse.getStatusLine().getStatusCode();
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/client/impl/ApacheConnectionManagerFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/ApacheConnectionManagerFactory.java
--- ./src/main/java/com/amazonaws/http/apache/client/impl/ApacheConnectionManagerFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/ApacheConnectionManagerFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.client.impl;
-
-import com.amazonaws.SDKGlobalConfiguration;
-import com.amazonaws.http.AmazonHttpClient;
-import com.amazonaws.http.DelegatingDnsResolver;
-import com.amazonaws.http.client.ConnectionManagerFactory;
-import com.amazonaws.http.conn.ssl.SdkTLSSocketFactory;
-import com.amazonaws.http.settings.HttpClientSettings;
-import com.amazonaws.internal.SdkSSLContext;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.HttpHost;
-import org.apache.http.config.ConnectionConfig;
-import org.apache.http.config.Registry;
-import org.apache.http.config.RegistryBuilder;
-import org.apache.http.config.SocketConfig;
-import org.apache.http.conn.HttpClientConnectionManager;
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.impl.conn.DefaultSchemePortResolver;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.apache.http.protocol.HttpContext;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.concurrent.TimeUnit;
-
-import static com.amazonaws.SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY;
-
-/**
- * Factory class to create connection manager used by the apache client.
- */
-public class ApacheConnectionManagerFactory implements
-        ConnectionManagerFactory<HttpClientConnectionManager> {
-
-    private final Log LOG = LogFactory.getLog(AmazonHttpClient.class);
-
-    @Override
-    public HttpClientConnectionManager create(final HttpClientSettings settings) {
-        ConnectionSocketFactory sslsf = getPreferredSocketFactory(settings);
-
-        final PoolingHttpClientConnectionManager cm = new
-                PoolingHttpClientConnectionManager(
-                createSocketFactoryRegistry(sslsf),
-                null,
-                DefaultSchemePortResolver.INSTANCE,
-                new DelegatingDnsResolver(settings.getDnsResolver()),
-                settings.getConnectionPoolTTL(),
-                TimeUnit.MILLISECONDS);
-
-        cm.setValidateAfterInactivity(settings.getValidateAfterInactivityMillis());
-        cm.setDefaultMaxPerRoute(settings.getMaxConnections());
-        cm.setMaxTotal(settings.getMaxConnections());
-        cm.setDefaultSocketConfig(buildSocketConfig(settings));
-        cm.setDefaultConnectionConfig(buildConnectionConfig(settings));
-
-        return cm;
-    }
-
-    private ConnectionSocketFactory getPreferredSocketFactory(HttpClientSettings settings) {
-        ConnectionSocketFactory sslsf = settings.getApacheHttpClientConfig().getSslSocketFactory();
-
-        return sslsf != null
-                ? sslsf
-                : new SdkTLSSocketFactory(
-                SdkSSLContext.getPreferredSSLContext(settings.getSecureRandom()),
-                getHostNameVerifier(settings));
-    }
-
-
-    private SocketConfig buildSocketConfig(HttpClientSettings settings) {
-        return SocketConfig.custom()
-                .setSoKeepAlive(settings.useTcpKeepAlive())
-                .setSoTimeout(settings.getSocketTimeout())
-                .setTcpNoDelay(true)
-                .build();
-    }
-
-    private ConnectionConfig buildConnectionConfig(HttpClientSettings settings) {
-
-        int socketBufferSize = Math.max(settings.getSocketBufferSize()[0],
-                settings.getSocketBufferSize()[1]);
-
-        return socketBufferSize <= 0
-                ? null
-                : ConnectionConfig.custom()
-                .setBufferSize(socketBufferSize)
-                .build();
-    }
-
-    private HostnameVerifier getHostNameVerifier
-            (HttpClientSettings options) {
-        // TODO Need to find a better way to handle these deprecations.
-        return options.useBrowserCompatibleHostNameVerifier()
-                ? SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
-                : SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER;
-    }
-
-    private Registry<ConnectionSocketFactory> createSocketFactoryRegistry(ConnectionSocketFactory sslSocketFactory) {
-
-        /*
-         * If SSL cert checking for endpoints has been explicitly disabled,
-         * register a new scheme for HTTPS that won't cause self-signed certs to
-         * error out.
-         */
-        if (SDKGlobalConfiguration.isCertCheckingDisabled()) {
-            if (LOG.isWarnEnabled()) {
-                LOG.warn("SSL Certificate checking for endpoints has been " +
-                        "explicitly disabled.");
-            }
-            sslSocketFactory = new TrustingSocketFactory();
-        }
-
-        return RegistryBuilder.<ConnectionSocketFactory>create()
-                .register("http", PlainConnectionSocketFactory.getSocketFactory())
-                .register("https", sslSocketFactory)
-                .build();
-    }
-
-    /**
-     * Simple implementation of SchemeSocketFactory (and
-     * LayeredSchemeSocketFactory) that bypasses SSL certificate checks. This
-     * class is only intended to be used for testing purposes.
-     */
-    private static class TrustingSocketFactory implements
-            LayeredConnectionSocketFactory {
-
-        private SSLContext sslcontext = null;
-
-        private static SSLContext createSSLContext() throws IOException {
-            try {
-                SSLContext context = SSLContext.getInstance("TLS");
-                context.init(null, new TrustManager[]{new TrustingX509TrustManager()}, null);
-                return context;
-            } catch (Exception e) {
-                throw new IOException(e.getMessage(), e);
-            }
-        }
-
-        @Override
-        public Socket createLayeredSocket(Socket socket, String target, int port, HttpContext context) throws IOException, UnknownHostException {
-            return getSSLContext().getSocketFactory().createSocket(socket,
-                    target, port, true);
-        }
-
-        @Override
-        public Socket createSocket(HttpContext context) throws IOException {
-            return getSSLContext().getSocketFactory().createSocket();
-        }
-
-        @Override
-        public Socket connectSocket(int connectTimeout, Socket sock, HttpHost host, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context) throws IOException {
-
-            SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock :
-                    createSocket(context));
-            if (localAddress != null) sslsock.bind(localAddress);
-
-
-            sslsock.connect(remoteAddress, connectTimeout);
-            // socket timeout is set internally by the
-            // PoolingHttpClientConnectionManager.
-            return sslsock;
-        }
-
-        private SSLContext getSSLContext() throws IOException {
-            if (this.sslcontext == null) this.sslcontext = createSSLContext();
-            return this.sslcontext;
-        }
-    }
-
-    /**
-     * Simple implementation of X509TrustManager that trusts all certificates.
-     * This class is only intended to be used for testing purposes.
-     */
-    private static class TrustingX509TrustManager implements X509TrustManager {
-        private static final X509Certificate[] X509_CERTIFICATES = new X509Certificate[0];
-
-        @Override
-        public X509Certificate[] getAcceptedIssuers() {
-            return X509_CERTIFICATES;
-        }
-
-        @Override
-        public void checkServerTrusted(X509Certificate[] chain, String authType)
-                throws CertificateException {
-            // No-op, to trust all certs
-        }
-
-        @Override
-        public void checkClientTrusted(X509Certificate[] chain, String authType)
-                throws CertificateException {
-            // No-op, to trust all certs
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/client/impl/ApacheHttpClientFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/ApacheHttpClientFactory.java
--- ./src/main/java/com/amazonaws/http/apache/client/impl/ApacheHttpClientFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/ApacheHttpClientFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.client.impl;
-
-import com.amazonaws.http.AmazonHttpClient;
-import com.amazonaws.http.IdleConnectionReaper;
-import com.amazonaws.http.apache.SdkProxyRoutePlanner;
-import com.amazonaws.http.apache.utils.ApacheUtils;
-import com.amazonaws.http.client.ConnectionManagerFactory;
-import com.amazonaws.http.client.HttpClientFactory;
-import com.amazonaws.http.conn.ClientConnectionManagerFactory;
-import com.amazonaws.http.conn.SdkConnectionKeepAliveStrategy;
-import com.amazonaws.http.protocol.SdkHttpRequestExecutor;
-import com.amazonaws.http.settings.HttpClientSettings;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.conn.ConnectionKeepAliveStrategy;
-import org.apache.http.conn.HttpClientConnectionManager;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
-
-/**
- * Factory class that builds the apache http client from the settings.
- */
-public class ApacheHttpClientFactory implements HttpClientFactory<ConnectionManagerAwareHttpClient> {
-
-    private static final Log LOG = LogFactory.getLog(AmazonHttpClient.class);
-    private final ConnectionManagerFactory<HttpClientConnectionManager>
-            cmFactory = new ApacheConnectionManagerFactory();
-
-    @Override
-    public ConnectionManagerAwareHttpClient create(HttpClientSettings settings) {
-        final HttpClientBuilder builder = HttpClients.custom();
-        // Note that it is important we register the original connection manager with the
-        // IdleConnectionReaper as it's required for the successful deregistration of managers
-        // from the reaper. See https://github.com/aws/aws-sdk-java/issues/722.
-        final HttpClientConnectionManager cm = cmFactory.create(settings);
-
-        builder.setRequestExecutor(new SdkHttpRequestExecutor())
-                .setKeepAliveStrategy(buildKeepAliveStrategy(settings))
-                .disableRedirectHandling()
-                .disableAutomaticRetries()
-                .setConnectionManager(ClientConnectionManagerFactory.wrap(cm));
-
-        // By default http client enables Gzip compression. So we disable it
-        // here.
-        // Apache HTTP client removes Content-Length, Content-Encoding and
-        // Content-MD5 headers when Gzip compression is enabled. Currently
-        // this doesn't affect S3 or Glacier which exposes these headers.
-        //
-        if (!(settings.useGzip())) {
-            builder.disableContentCompression();
-        }
-
-        HttpResponseInterceptor itcp = new CRC32ChecksumResponseInterceptor();
-        if (settings.calculateCRC32FromCompressedData()) {
-            builder.addInterceptorFirst(itcp);
-        } else {
-            builder.addInterceptorLast(itcp);
-        }
-
-        addProxyConfig(builder, settings);
-
-        final ConnectionManagerAwareHttpClient httpClient = new SdkHttpClient(builder.build(), cm);
-
-        if (settings.useReaper()) {
-            IdleConnectionReaper.registerConnectionManager(cm, settings.getMaxIdleConnectionTime());
-        }
-
-        return httpClient;
-    }
-
-    private void addProxyConfig(HttpClientBuilder builder,
-                                HttpClientSettings settings) {
-        if (settings.isProxyEnabled()) {
-
-            LOG.info("Configuring Proxy. Proxy Host: " + settings.getProxyHost() + " " +
-                    "Proxy Port: " + settings.getProxyPort());
-
-            builder.setRoutePlanner(new SdkProxyRoutePlanner(
-                    settings.getProxyHost(), settings.getProxyPort(), settings.getNonProxyHosts()));
-
-            if (settings.isAuthenticatedProxy()) {
-                builder.setDefaultCredentialsProvider(ApacheUtils.newProxyCredentialsProvider(settings));
-            }
-        }
-    }
-
-    private ConnectionKeepAliveStrategy buildKeepAliveStrategy(HttpClientSettings settings) {
-        return settings.getMaxIdleConnectionTime() > 0
-                ? new SdkConnectionKeepAliveStrategy(settings.getMaxIdleConnectionTime())
-                : null;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/client/impl/ConnectionManagerAwareHttpClient.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/ConnectionManagerAwareHttpClient.java
--- ./src/main/java/com/amazonaws/http/apache/client/impl/ConnectionManagerAwareHttpClient.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/ConnectionManagerAwareHttpClient.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.client.impl;
-
-import org.apache.http.client.HttpClient;
-import org.apache.http.conn.HttpClientConnectionManager;
-
-/**
- * An extension of Apache's HttpClient that expose the connection manager
- * associated with the client.
- */
-public interface ConnectionManagerAwareHttpClient extends HttpClient {
-
-    /**
-     * Returns the {@link HttpClientConnectionManager} associated with the
-     * http client.
-     */
-    HttpClientConnectionManager getHttpClientConnectionManager();
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/client/impl/CRC32ChecksumResponseInterceptor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/CRC32ChecksumResponseInterceptor.java
--- ./src/main/java/com/amazonaws/http/apache/client/impl/CRC32ChecksumResponseInterceptor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/CRC32ChecksumResponseInterceptor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,81 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.client.impl;
-
-import com.amazonaws.util.CRC32ChecksumCalculatingInputStream;
-import com.amazonaws.util.IOUtils;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.entity.HttpEntityWrapper;
-import org.apache.http.protocol.HttpContext;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-public class CRC32ChecksumResponseInterceptor implements HttpResponseInterceptor {
-
-    @Override
-    public void process(HttpResponse response, final HttpContext context)
-            throws HttpException, IOException {
-        final HttpEntity entity = response.getEntity();
-
-        // Only Json protocol has this header, we only wrap CRC32ChecksumCalculatingInputStream in json protocol clients.
-        Header[] headers = response.getHeaders("x-amz-crc32");
-        if (entity == null || headers == null || headers.length == 0) {
-            return;
-        }
-        HttpEntity crc32ResponseEntity = new HttpEntityWrapper(entity) {
-
-            private final InputStream content = new CRC32ChecksumCalculatingInputStream(
-                    wrappedEntity.getContent());
-
-            @Override
-            public InputStream getContent() throws IOException {
-                return content;
-            }
-
-            /**
-             * It's important to override writeTo. Some versions of Apache HTTP
-             * client use writeTo for {@link org.apache.http.entity.BufferedHttpEntity}
-             * and the default implementation just delegates to the wrapped entity
-             * which completely bypasses our CRC32 calculating input stream. The
-             * {@link org.apache.http.entity.BufferedHttpEntity} is used for the
-             * request timeout and client execution timeout features.
-             *
-             * @see <a href="https://github.com/aws/aws-sdk-java/issues/526">Issue #526</a>
-             *
-             * @param outstream OutputStream to write contents to
-             */
-            @Override
-            public void writeTo(OutputStream outstream) throws IOException {
-                try {
-                    IOUtils.copy(this.getContent(), outstream);
-                } finally {
-                    this.getContent().close();
-                }
-            }
-        };
-
-        response.setEntity(crc32ResponseEntity);
-        context.setAttribute(CRC32ChecksumCalculatingInputStream.class.getName(),
-                             crc32ResponseEntity.getContent());
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/client/impl/SdkHttpClient.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/SdkHttpClient.java
--- ./src/main/java/com/amazonaws/http/apache/client/impl/SdkHttpClient.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/client/impl/SdkHttpClient.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.client.impl;
-
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.HttpClientConnectionManager;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.HttpContext;
-
-import java.io.IOException;
-
-/**
- * An instance of {@link ConnectionManagerAwareHttpClient} that delegates all the requests to the given http client.
- */
-public class SdkHttpClient implements
-        ConnectionManagerAwareHttpClient {
-
-    private final HttpClient delegate;
-
-    private final HttpClientConnectionManager cm;
-
-    public SdkHttpClient(final HttpClient delegate,
-                         final HttpClientConnectionManager cm) {
-        if (delegate == null) {
-            throw new IllegalArgumentException("delegate " +
-                    "cannot be null");
-        }
-        if (cm == null) {
-            throw new IllegalArgumentException("connection manager " +
-                    "cannot be null");
-        }
-        this.delegate = delegate;
-        this.cm = cm;
-    }
-
-    @Override
-    public HttpParams getParams() {
-        return delegate.getParams();
-    }
-
-    @Override
-    public ClientConnectionManager getConnectionManager() {
-        return delegate.getConnectionManager();
-    }
-
-    @Override
-    public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
-        return delegate.execute(request);
-    }
-
-    @Override
-    public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
-        return delegate.execute(request, context);
-    }
-
-    @Override
-    public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException {
-        return delegate.execute(target, request);
-    }
-
-    @Override
-    public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException {
-        return delegate.execute(target, request, context);
-    }
-
-    @Override
-    public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
-        return delegate.execute(request, responseHandler);
-    }
-
-    @Override
-    public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
-        return delegate.execute(request, responseHandler, context);
-    }
-
-    @Override
-    public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
-        return delegate.execute(target, request, responseHandler);
-    }
-
-    @Override
-    public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
-        return delegate.execute(target, request, responseHandler, context);
-    }
-
-    @Override
-    public HttpClientConnectionManager getHttpClientConnectionManager() {
-        return cm;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/request/impl/ApacheHttpRequestFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/request/impl/ApacheHttpRequestFactory.java
--- ./src/main/java/com/amazonaws/http/apache/request/impl/ApacheHttpRequestFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/request/impl/ApacheHttpRequestFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.request.impl;
-
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.ProxyAuthenticationMethod;
-import com.amazonaws.Request;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.http.HttpMethodName;
-import com.amazonaws.http.RepeatableInputStreamRequestEntity;
-import com.amazonaws.http.apache.utils.ApacheUtils;
-import com.amazonaws.http.request.HttpRequestFactory;
-import com.amazonaws.http.settings.HttpClientSettings;
-import com.amazonaws.util.FakeIOException;
-import com.amazonaws.util.SdkHttpUtils;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map.Entry;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHeaders;
-import org.apache.http.client.config.AuthSchemes;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpOptions;
-import org.apache.http.client.methods.HttpPatch;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpRequestBase;
-
-/**
- * Responsible for creating Apache HttpClient 4 request objects.
- */
-public class ApacheHttpRequestFactory implements
-        HttpRequestFactory<HttpRequestBase> {
-
-    private static final String DEFAULT_ENCODING = "UTF-8";
-
-    private static final List<String> ignoreHeaders = Arrays.asList
-            (HttpHeaders.CONTENT_LENGTH, HttpHeaders.HOST);
-
-    @Override
-    public HttpRequestBase create(final Request<?> request,
-                                  final HttpClientSettings settings)
-            throws
-            FakeIOException {
-        URI endpoint = request.getEndpoint();
-
-        /*
-         * HttpClient cannot handle url in pattern of "http://host//path", so we
-         * have to escape the double-slash between endpoint and resource-path
-         * into "/%2F"
-         */
-        String uri = SdkHttpUtils.appendUri(endpoint.toString(), request
-                .getResourcePath(), true);
-        String encodedParams = SdkHttpUtils.encodeParameters(request);
-
-        /*
-         * For all non-POST requests, and any POST requests that already have a
-         * payload, we put the encoded params directly in the URI, otherwise,
-         * we'll put them in the POST request's payload.
-         */
-        boolean requestHasNoPayload = request.getContent() != null;
-        boolean requestIsPost = request.getHttpMethod() == HttpMethodName.POST;
-        boolean putParamsInUri = !requestIsPost || requestHasNoPayload;
-        if (encodedParams != null && putParamsInUri) {
-            uri += "?" + encodedParams;
-        }
-
-        final HttpRequestBase base = createApacheRequest(request, uri, encodedParams);
-        addHeadersToRequest(base, request);
-        addRequestConfig(base, request, settings);
-
-        return base;
-    }
-
-    private void addRequestConfig(final HttpRequestBase base,
-                                  final Request<?> request,
-                                  final HttpClientSettings settings) {
-        final RequestConfig.Builder requestConfigBuilder = RequestConfig
-                .custom()
-                .setConnectionRequestTimeout(settings.getConnectionPoolRequestTimeout())
-                .setConnectTimeout(settings.getConnectionTimeout())
-                .setSocketTimeout(settings.getSocketTimeout())
-                .setLocalAddress(settings.getLocalAddress());
-
-        /*
-         * Enable 100-continue support for PUT operations, since this is
-         * where we're potentially uploading large amounts of data and want
-         * to find out as early as possible if an operation will fail. We
-         * don't want to do this for all operations since it will cause
-         * extra latency in the network interaction.
-         */
-        if (HttpMethodName.PUT == request.getHttpMethod() && settings.isUseExpectContinue()) {
-            requestConfigBuilder.setExpectContinueEnabled(true);
-        }
-
-        addProxyConfig(requestConfigBuilder, settings);
-
-        base.setConfig(requestConfigBuilder.build());
-    }
-
-    private HttpRequestBase createApacheRequest(Request<?> request, String uri, String encodedParams) throws FakeIOException {
-        switch (request.getHttpMethod()) {
-            case HEAD:
-                return new HttpHead(uri);
-            case GET:
-                return wrapEntity(request, new HttpGetWithBody(uri), encodedParams);
-            case DELETE:
-                return new HttpDelete(uri);
-            case OPTIONS:
-                return new HttpOptions(uri);
-            case PATCH:
-                return wrapEntity(request, new HttpPatch(uri), encodedParams);
-            case POST:
-                return wrapEntity(request, new HttpPost(uri), encodedParams);
-            case PUT:
-                return wrapEntity(request, new HttpPut(uri), encodedParams);
-            default:
-                throw new SdkClientException("Unknown HTTP method name: " + request.getHttpMethod());
-        }
-    }
-
-    private HttpRequestBase wrapEntity(Request<?> request,
-                                       HttpEntityEnclosingRequestBase entityEnclosingRequest,
-                                       String encodedParams) throws FakeIOException {
-
-        if (HttpMethodName.POST == request.getHttpMethod()) {
-            /*
-             * If there isn't any payload content to include in this request,
-             * then try to include the POST parameters in the query body,
-             * otherwise, just use the query string. For all AWS Query services,
-             * the best behavior is putting the params in the request body for
-             * POST requests, but we can't do that for S3.
-             */
-            if (request.getContent() == null && encodedParams != null) {
-                entityEnclosingRequest.setEntity(ApacheUtils.newStringEntity(encodedParams));
-            } else {
-                entityEnclosingRequest.setEntity(new RepeatableInputStreamRequestEntity(request));
-            }
-        } else {
-            /*
-             * We should never reuse the entity of the previous request, since
-             * reading from the buffered entity will bypass reading from the
-             * original request content. And if the content contains InputStream
-             * wrappers that were added for validation-purpose (e.g.
-             * Md5DigestCalculationInputStream), these wrappers would never be
-             * read and updated again after AmazonHttpClient resets it in
-             * preparation for the retry. Eventually, these wrappers would
-             * return incorrect validation result.
-             */
-            if (request.getContent() != null) {
-                HttpEntity entity = new RepeatableInputStreamRequestEntity(request);
-                if (request.getHeaders().get(HttpHeaders.CONTENT_LENGTH) == null) {
-                    entity = ApacheUtils.newBufferedHttpEntity(entity);
-                }
-                entityEnclosingRequest.setEntity(entity);
-            }
-        }
-        return entityEnclosingRequest;
-    }
-
-    /**
-     * Configures the headers in the specified Apache HTTP request.
-     */
-    private void addHeadersToRequest(HttpRequestBase httpRequest, Request<?> request) {
-
-        httpRequest.addHeader(HttpHeaders.HOST, getHostHeaderValue(request.getEndpoint()));
-
-        // Copy over any other headers already in our request
-        for (Entry<String, String> entry : request.getHeaders().entrySet()) {
-            /*
-             * HttpClient4 fills in the Content-Length header and complains if
-             * it's already present, so we skip it here. We also skip the Host
-             * header to avoid sending it twice, which will interfere with some
-             * signing schemes.
-             */
-            if (!(ignoreHeaders.contains(entry.getKey()))) {
-                httpRequest.addHeader(entry.getKey(), entry.getValue());
-            }
-        }
-
-        /* Set content type and encoding */
-        if (httpRequest.getHeaders(HttpHeaders.CONTENT_TYPE) == null || httpRequest
-                .getHeaders
-                        (HttpHeaders.CONTENT_TYPE).length == 0) {
-            httpRequest.addHeader(HttpHeaders.CONTENT_TYPE,
-                    "application/x-www-form-urlencoded; " +
-                            "charset=" + DEFAULT_ENCODING.toLowerCase());
-        }
-    }
-
-    private String getHostHeaderValue(final URI endpoint) {
-        /*
-         * Apache HttpClient omits the port number in the Host header (even if
-         * we explicitly specify it) if it's the default port for the protocol
-         * in use. To ensure that we use the same Host header in the request and
-         * in the calculated string to sign (even if Apache HttpClient changed
-         * and started honoring our explicit host with endpoint), we follow this
-         * same behavior here and in the QueryString signer.
-         */
-        return SdkHttpUtils.isUsingNonDefaultPort(endpoint)
-                ? endpoint.getHost() + ":" + endpoint.getPort()
-                : endpoint.getHost();
-    }
-
-    /**
-     * Update the provided request configuration builder to specify the proxy authentication schemes that should be used when
-     * authenticating against the HTTP proxy.
-     *
-     * @see ClientConfiguration#setProxyAuthenticationMethods(List)
-     */
-    private void addProxyConfig(RequestConfig.Builder requestConfigBuilder, HttpClientSettings settings) {
-        if (settings.isProxyEnabled() && settings.isAuthenticatedProxy() && settings.getProxyAuthenticationMethods() != null) {
-            List<String> apacheAuthenticationSchemes = new ArrayList<String>();
-
-            for (ProxyAuthenticationMethod authenticationMethod : settings.getProxyAuthenticationMethods()) {
-                apacheAuthenticationSchemes.add(toApacheAuthenticationScheme(authenticationMethod));
-            }
-
-            requestConfigBuilder.setProxyPreferredAuthSchemes(apacheAuthenticationSchemes);
-        }
-    }
-
-    /**
-     * Convert the customer-facing authentication method into an apache-specific authentication method.
-     */
-    private String toApacheAuthenticationScheme(ProxyAuthenticationMethod authenticationMethod) {
-        if (authenticationMethod == null) {
-            throw new IllegalStateException("The configured proxy authentication methods must not be null.");
-        }
-
-        switch (authenticationMethod) {
-            case NTLM: return AuthSchemes.NTLM;
-            case BASIC: return AuthSchemes.BASIC;
-            case DIGEST: return AuthSchemes.DIGEST;
-            case SPNEGO: return AuthSchemes.SPNEGO;
-            case KERBEROS: return AuthSchemes.KERBEROS;
-            default: throw new IllegalStateException("Unknown authentication scheme: " + authenticationMethod);
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/request/impl/HttpGetWithBody.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/request/impl/HttpGetWithBody.java
--- ./src/main/java/com/amazonaws/http/apache/request/impl/HttpGetWithBody.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/request/impl/HttpGetWithBody.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,36 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.http.apache.request.impl;
-
-import java.net.URI;
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-import org.apache.http.client.methods.HttpGet;
-
-/**
- * Allows sending a GET request with a request body.
- */
-public class HttpGetWithBody extends HttpEntityEnclosingRequestBase {
-
-    public HttpGetWithBody(String uri) {
-        super();
-        setURI(URI.create(uri));
-    }
-
-    @Override
-    public String getMethod() {
-        return HttpGet.METHOD_NAME;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/SdkProxyRoutePlanner.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/SdkProxyRoutePlanner.java
--- ./src/main/java/com/amazonaws/http/apache/SdkProxyRoutePlanner.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/SdkProxyRoutePlanner.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,75 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache;
-
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.impl.conn.DefaultRoutePlanner;
-import org.apache.http.impl.conn.DefaultSchemePortResolver;
-import org.apache.http.protocol.HttpContext;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory;
-import com.amazonaws.util.StringUtils;
-
-/**
- * SdkProxyRoutePlanner delegates a Proxy Route Planner from the settings instead of the
- * system properties. It will use the proxy created from proxyHost and proxyPort and
- * filter the hosts who matches nonProxyHosts pattern.
- *
- * @see ApacheHttpClientFactory#create(com.amazonaws.http.settings.HttpClientSettings)
- */
-@SdkInternalApi
-public class SdkProxyRoutePlanner extends DefaultRoutePlanner {
-    private HttpHost proxy;
-    private String[] hostPatterns;
-
-    public SdkProxyRoutePlanner(String proxyHost, int proxyPort, String nonProxyHosts) {
-        super(DefaultSchemePortResolver.INSTANCE);
-        proxy = new HttpHost(proxyHost, proxyPort);
-        parseNonProxyHosts(nonProxyHosts);
-    }
-
-    private void parseNonProxyHosts(String nonProxyHosts) {
-        if (!StringUtils.isNullOrEmpty(nonProxyHosts)) {
-            String[] hosts = nonProxyHosts.split("\\|");
-            hostPatterns = new String[hosts.length];
-            for (int i = 0; i < hosts.length; ++i) {
-                hostPatterns[i] = hosts[i].toLowerCase().replace("*", ".*?");
-            }
-        }
-    }
-
-    boolean doesTargetMatchNonProxyHosts(HttpHost target) {
-        if (hostPatterns == null) {
-            return false;
-        }
-        String targetHost = target.getHostName().toLowerCase();
-        for (String pattern : hostPatterns) {
-            if (targetHost.matches(pattern)) return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected HttpHost determineProxy(
-        final HttpHost target,
-        final HttpRequest request,
-        final HttpContext context) throws HttpException {
-
-        return doesTargetMatchNonProxyHosts(target) ? null : proxy;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/apache/utils/ApacheUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/utils/ApacheUtils.java
--- ./src/main/java/com/amazonaws/http/apache/utils/ApacheUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/apache/utils/ApacheUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.apache.utils;
-
-import com.amazonaws.Request;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.http.settings.HttpClientSettings;
-import com.amazonaws.util.FakeIOException;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpStatus;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.NTCredentials;
-import org.apache.http.client.AuthCache;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.entity.BufferedHttpEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-import org.apache.http.protocol.HttpContext;
-
-public class ApacheUtils {
-
-    /**
-     * Checks if the request was successful or not based on the status code.
-     *
-     * @param response HTTP response
-     * @return True if the request was successful (i.e. has a 2xx status code), false otherwise.
-     */
-    public static boolean isRequestSuccessful(org.apache.http.HttpResponse response) {
-        int status = response.getStatusLine().getStatusCode();
-        return status / 100 == HttpStatus.SC_OK / 100;
-    }
-
-    /**
-     * Creates and initializes an HttpResponse object suitable to be passed to an HTTP response
-     * handler object.
-     *
-     * @param request Marshalled request object.
-     * @param method  The HTTP method that was invoked to get the response.
-     * @param context The HTTP context associated with the request and response.
-     * @return The new, initialized HttpResponse object ready to be passed to an HTTP response
-     * handler object.
-     * @throws IOException If there were any problems getting any response information from the
-     *                     HttpClient method object.
-     */
-    public static HttpResponse createResponse(Request<?> request,
-                                        HttpRequestBase method,
-                                        org.apache.http.HttpResponse apacheHttpResponse,
-                                        HttpContext context) throws IOException {
-        HttpResponse httpResponse = new HttpResponse(request, method, context);
-
-        if (apacheHttpResponse.getEntity() != null) {
-            httpResponse.setContent(apacheHttpResponse.getEntity().getContent());
-        }
-
-        httpResponse.setStatusCode(apacheHttpResponse.getStatusLine().getStatusCode());
-        httpResponse.setStatusText(apacheHttpResponse.getStatusLine().getReasonPhrase());
-        for (Header header : apacheHttpResponse.getAllHeaders()) {
-            httpResponse.addHeader(header.getName(), header.getValue());
-        }
-
-        return httpResponse;
-    }
-
-    /**
-     * Utility function for creating a new StringEntity and wrapping any errors
-     * as a SdkClientException.
-     *
-     * @param s The string contents of the returned HTTP entity.
-     * @return A new StringEntity with the specified contents.
-     */
-    public static HttpEntity newStringEntity(String s) {
-        try {
-            return new StringEntity(s);
-        } catch (UnsupportedEncodingException e) {
-            throw new SdkClientException("Unable to create HTTP entity: " + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Utility function for creating a new BufferedEntity and wrapping any errors
-     * as a SdkClientException.
-     *
-     * @param entity The HTTP entity to wrap with a buffered HTTP entity.
-     * @return A new BufferedHttpEntity wrapping the specified entity.
-     * @throws FakeIOException only for test simulation
-     */
-    public static HttpEntity newBufferedHttpEntity(HttpEntity entity) throws
-            FakeIOException {
-        try {
-            return new BufferedHttpEntity(entity);
-        } catch (FakeIOException e) {
-            // Only for test simulation.
-            throw e;
-        } catch (IOException e) {
-            throw new SdkClientException("Unable to create HTTP entity: " + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * Returns a new HttpClientContext used for request execution.
-     */
-    public static HttpClientContext newClientContext(HttpClientSettings settings,
-                                                     Map<String, ? extends Object>
-                                                             attributes) {
-        final HttpClientContext clientContext = new HttpClientContext();
-
-        if (attributes != null && !attributes.isEmpty()) {
-            for (Map.Entry<String, ?> entry : attributes.entrySet()) {
-                clientContext.setAttribute(entry.getKey(), entry.getValue());
-            }
-        }
-
-        addPreemptiveAuthenticationProxy(clientContext, settings);
-        return clientContext;
-
-    }
-
-    /**
-     * Returns a new Credentials Provider for use with proxy authentication.
-     */
-    public static CredentialsProvider newProxyCredentialsProvider
-    (HttpClientSettings settings) {
-        final CredentialsProvider provider = new BasicCredentialsProvider();
-        provider.setCredentials(newAuthScope(settings), newNTCredentials(settings));
-        return provider;
-    }
-
-    /**
-     * Returns a new instance of NTCredentials used for proxy authentication.
-     */
-    private static Credentials newNTCredentials(HttpClientSettings settings) {
-        return new NTCredentials(settings.getProxyUsername(),
-                settings.getProxyPassword(),
-                settings.getProxyWorkstation(),
-                settings.getProxyDomain());
-    }
-
-    /**
-     * Returns a new instance of AuthScope used for proxy authentication.
-     */
-    private static AuthScope newAuthScope(HttpClientSettings settings) {
-        return new AuthScope(settings.getProxyHost(), settings.getProxyPort());
-    }
-
-    private static void addPreemptiveAuthenticationProxy(HttpClientContext clientContext,
-                                                         HttpClientSettings settings) {
-
-        if (settings.isPreemptiveBasicProxyAuth()) {
-            HttpHost targetHost = new HttpHost(settings.getProxyHost(), settings
-                    .getProxyPort());
-            final CredentialsProvider credsProvider = newProxyCredentialsProvider(settings);
-            // Create AuthCache instance
-            AuthCache authCache = new BasicAuthCache();
-            // Generate BASIC scheme object and add it to the local auth cache
-            BasicScheme basicAuth = new BasicScheme();
-            authCache.put(targetHost, basicAuth);
-
-            clientContext.setCredentialsProvider(credsProvider);
-            clientContext.setAuthCache(authCache);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/AwsErrorResponseHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/AwsErrorResponseHandler.java
--- ./src/main/java/com/amazonaws/http/AwsErrorResponseHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/AwsErrorResponseHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,79 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.AWSRequestMetrics;
-
-/**
- * Wrapper around protocol specific error handler to deal with some default scenarios and fill in common information.
- */
-@SdkInternalApi
-class AwsErrorResponseHandler implements HttpResponseHandler<AmazonServiceException> {
-
-    private final HttpResponseHandler<AmazonServiceException> delegate;
-    private final AWSRequestMetrics awsRequestMetrics;
-
-    AwsErrorResponseHandler(HttpResponseHandler<AmazonServiceException> errorResponseHandler,
-                            AWSRequestMetrics awsRequestMetrics) {
-        this.delegate = errorResponseHandler;
-        this.awsRequestMetrics = awsRequestMetrics;
-    }
-
-    @Override
-    public AmazonServiceException handle(HttpResponse response) throws Exception {
-        final AmazonServiceException ase = handleAse(response);
-        ase.setStatusCode(response.getStatusCode());
-        ase.setServiceName(response.getRequest().getServiceName());
-        awsRequestMetrics.addPropertyWith(AWSRequestMetrics.Field.AWSRequestID, ase.getRequestId())
-                .addPropertyWith(AWSRequestMetrics.Field.AWSErrorCode, ase.getErrorCode())
-                .addPropertyWith(AWSRequestMetrics.Field.StatusCode, ase.getStatusCode());
-        return ase;
-    }
-
-    private AmazonServiceException handleAse(HttpResponse response) throws Exception {
-        final int statusCode = response.getStatusCode();
-        try {
-            return delegate.handle(response);
-        } catch(InterruptedException e) {
-            throw e;
-        } catch (Exception e) {
-            // If the errorResponseHandler doesn't work, then check for error responses that don't have any content
-            if (statusCode == 413) {
-                AmazonServiceException exception = new AmazonServiceException("Request entity too large");
-                exception.setServiceName(response.getRequest().getServiceName());
-                exception.setStatusCode(statusCode);
-                exception.setErrorType(AmazonServiceException.ErrorType.Client);
-                exception.setErrorCode("Request entity too large");
-                return exception;
-            } else if (statusCode >= 500 && statusCode < 600) {
-                AmazonServiceException exception = new AmazonServiceException(response.getStatusText());
-                exception.setServiceName(response.getRequest().getServiceName());
-                exception.setStatusCode(statusCode);
-                exception.setErrorType(AmazonServiceException.ErrorType.Service);
-                exception.setErrorCode(response.getStatusText());
-                return exception;
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    @Override
-    public boolean needsConnectionLeftOpen() {
-        return delegate.needsConnectionLeftOpen();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/client/ConnectionManagerFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/client/ConnectionManagerFactory.java
--- ./src/main/java/com/amazonaws/http/client/ConnectionManagerFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/client/ConnectionManagerFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.client;
-
-import com.amazonaws.annotation.Beta;
-import com.amazonaws.http.settings.HttpClientSettings;
-
-/**
- * Factory interface that can be used for create ConnectionManager used by
- * the underlying http client.
- */
-@Beta
-public interface ConnectionManagerFactory<T> {
-
-    T create(final HttpClientSettings settings);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/client/HttpClientFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/client/HttpClientFactory.java
--- ./src/main/java/com/amazonaws/http/client/HttpClientFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/client/HttpClientFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.client;
-
-import com.amazonaws.annotation.Beta;
-import com.amazonaws.http.settings.HttpClientSettings;
-
-
-/**
- * Factory interface that can be used for creating the underlying http client
- * for request execution.
- */
-@Beta
-public interface HttpClientFactory<T> {
-
-    T create(HttpClientSettings settings);
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ClientConnectionManagerFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ClientConnectionManagerFactory.java
--- ./src/main/java/com/amazonaws/http/conn/ClientConnectionManagerFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ClientConnectionManagerFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,87 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.conn;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.conn.ConnectionRequest;
-import org.apache.http.conn.HttpClientConnectionManager;
-import org.apache.http.pool.ConnPoolControl;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-public class ClientConnectionManagerFactory {
-    private static final Log log = LogFactory.getLog(ClientConnectionManagerFactory.class);
-
-    /**
-     * Returns a wrapped instance of {@link HttpClientConnectionManager}
-     * to capture the necessary performance metrics.
-     *
-     * @param orig the target instance to be wrapped
-     */
-    public static HttpClientConnectionManager wrap
-    (HttpClientConnectionManager orig) {
-        if (orig instanceof Wrapped)
-            throw new IllegalArgumentException();
-        final Class<?>[] interfaces;
-        if (orig instanceof ConnPoolControl) {
-            interfaces = new Class<?>[]{
-                    HttpClientConnectionManager.class,
-                    ConnPoolControl.class,
-                    Wrapped.class
-            };
-        } else {
-            interfaces = new Class<?>[]{
-                    HttpClientConnectionManager.class,
-                    Wrapped.class
-            };
-        }
-        return (HttpClientConnectionManager) Proxy.newProxyInstance(
-                // https://github.com/aws/aws-sdk-java/pull/48#issuecomment-29454423
-                ClientConnectionManagerFactory.class.getClassLoader(),
-                interfaces,
-                new Handler(orig));
-    }
-
-    /**
-     * The handler behind the dynamic proxy for {@link HttpClientConnectionManager}
-     * so that the any returned instance of {@link ConnectionRequest} can
-     * further wrapped for capturing performance metrics.
-     */
-    private static class Handler implements InvocationHandler {
-        private final HttpClientConnectionManager orig;
-
-        Handler(HttpClientConnectionManager real) {
-            this.orig = real;
-        }
-
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            try {
-                Object ret = method.invoke(orig, args);
-                return ret instanceof ConnectionRequest
-                        ? ClientConnectionRequestFactory.wrap((ConnectionRequest) ret)
-                        : ret
-                        ;
-            } catch (InvocationTargetException e) {
-                log.debug("", e);
-                throw e.getCause();
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ClientConnectionRequestFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ClientConnectionRequestFactory.java
--- ./src/main/java/com/amazonaws/http/conn/ClientConnectionRequestFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ClientConnectionRequestFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,83 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.conn;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.conn.ConnectionRequest;
-
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.metrics.ServiceLatencyProvider;
-import com.amazonaws.util.AWSServiceMetrics;
-
-class ClientConnectionRequestFactory {
-    private static final Log log = LogFactory.getLog(ClientConnectionRequestFactory.class);
-    private static final Class<?>[] interfaces = {
-            ConnectionRequest.class,
-        Wrapped.class
-    };
-
-    /**
-     * Returns a wrapped instance of {@link ConnectionRequest}
-     * to capture the necessary performance metrics.
-     * @param orig the target instance to be wrapped
-     */
-    static ConnectionRequest wrap(ConnectionRequest orig) {
-        if (orig instanceof Wrapped)
-            throw new IllegalArgumentException();
-        return (ConnectionRequest) Proxy.newProxyInstance(
-                // https://github.com/aws/aws-sdk-java/pull/48#issuecomment-29454423
-                ClientConnectionRequestFactory.class.getClassLoader(),
-                interfaces,
-                new Handler(orig));
-    }
-
-    /**
-     * The handler behind the dynamic proxy for {@link ConnectionRequest}
-     * so that the latency of the
-     * {@link ConnectionRequest#get(long, java.util.concurrent.TimeUnit)}
-     * can be captured.
-     */
-    private static class Handler implements InvocationHandler {
-        private final ConnectionRequest orig;
-        Handler(ConnectionRequest orig) {
-            this.orig = orig;
-        }
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            try {
-                if ("get".equals(method.getName())) {
-                    ServiceLatencyProvider latencyProvider = new ServiceLatencyProvider(
-                            AWSServiceMetrics.HttpClientGetConnectionTime);
-                    try {
-                        return method.invoke(orig, args);
-                    } finally {
-                        AwsSdkMetrics.getServiceMetricCollector()
-                                .collectLatency(latencyProvider.endTiming());
-                    }
-                }
-                return method.invoke(orig, args);
-            } catch (InvocationTargetException e) {
-                log.debug("", e);
-                throw e.getCause();
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/SdkConnectionKeepAliveStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/SdkConnectionKeepAliveStrategy.java
--- ./src/main/java/com/amazonaws/http/conn/SdkConnectionKeepAliveStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/SdkConnectionKeepAliveStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,57 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.conn;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.conn.ConnectionKeepAliveStrategy;
-import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
-import org.apache.http.protocol.HttpContext;
-
-/**
- * The AWS SDK for Java's implementation of the
- * {@code ConnectionKeepAliveStrategy} interface. Allows a user-configurable
- * maximum idle time for connections.
- */
-public class SdkConnectionKeepAliveStrategy
-        implements ConnectionKeepAliveStrategy {
-
-    private final long maxIdleTime;
-
-    /**
-     * @param maxIdleTime the maximum time a connection may be idle
-     */
-    public SdkConnectionKeepAliveStrategy(long maxIdleTime) {
-        this.maxIdleTime = maxIdleTime;
-    }
-
-    @Override
-    public long getKeepAliveDuration(
-            HttpResponse response,
-            HttpContext context) {
-
-        // If there's a Keep-Alive timeout directive in the response and it's
-        // shorter than our configured max, honor that. Otherwise go with the
-        // configured maximum.
-
-        long duration = DefaultConnectionKeepAliveStrategy.INSTANCE
-                .getKeepAliveDuration(response, context);
-
-        if (0 < duration && duration < maxIdleTime) {
-            return duration;
-        }
-
-        return maxIdleTime;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ssl/MasterSecretValidators.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/MasterSecretValidators.java
--- ./src/main/java/com/amazonaws/http/conn/ssl/MasterSecretValidators.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/MasterSecretValidators.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.conn.ssl;
-
-import java.net.Socket;
-
-import com.amazonaws.http.conn.ssl.privileged.PrivilegedMasterSecretValidator;
-import com.amazonaws.util.JavaVersionParser;
-import com.amazonaws.util.JavaVersionParser.JavaVersion;
-
-public class MasterSecretValidators {
-
-    // Versions that the SKIP-TLS bug has been fixed in for each affected major version
-    private static final JavaVersion FIXED_JAVA_6 = new JavaVersion(1, 6, 0, 91);
-    private static final JavaVersion FIXED_JAVA_7 = new JavaVersion(1, 7, 0, 51);
-    private static final JavaVersion FIXED_JAVA_8 = new JavaVersion(1, 8, 0, 31);
-
-    /**
-     * Interface to validate the master secret of a SSL session
-     */
-    public interface MasterSecretValidator {
-        /**
-         * @param socket
-         *            SSLSocket containing master secret
-         * @return True if master secret is considered valid, false otherwise
-         */
-        public boolean isMasterSecretValid(final Socket socket);
-    }
-
-    /**
-     * The implementation of {@link MasterSecretValidator} depends on the JVM version. Certain JVMs
-     * are affected by a serious bug that could allow a malicious MITM to negotiate a null master
-     * secret. Non-affected JVMs return a dummy implementation that always returns true
-     * 
-     * @see http://www.oracle.com/technetwork/topics/security/cpujan2015-1972971.html
-     * @see https://access.redhat.com/security/cve/CVE-2014-6593
-     * @return The correct implementation of {@link MasterSecretValidator}
-     */
-    public static MasterSecretValidator getMasterSecretValidator() {
-        return getMasterSecretValidator(JavaVersionParser.getCurrentJavaVersion());
-    }
-
-    /**
-     * @param javaVersion
-     *            Current Java version
-     * @return An appropriate {@link MasterSecretValidator} per the Java version in use
-     */
-    public static MasterSecretValidator getMasterSecretValidator(JavaVersion javaVersion) {
-        switch (javaVersion.getKnownVersion()) {
-        case JAVA_6:
-            if (javaVersion.compareTo(FIXED_JAVA_6) < 0) {
-                return new PrivilegedMasterSecretValidator();
-            }
-            break;
-        case JAVA_7:
-            if (javaVersion.compareTo(FIXED_JAVA_7) < 0) {
-                return new PrivilegedMasterSecretValidator();
-            }
-            break;
-        case JAVA_8:
-            if (javaVersion.compareTo(FIXED_JAVA_8) < 0) {
-                return new PrivilegedMasterSecretValidator();
-            }
-            break;
-        default:
-            break;
-
-        }
-        return new NoOpMasterSecretValidator();
-
-    }
-
-    /**
-     * Dummy implementation of {@link MasterSecretValidator} that always returns true. For JVMs that
-     * aren't affected by the SKIP-TLS bug
-     */
-    public static class NoOpMasterSecretValidator implements MasterSecretValidator {
-
-        @Override
-        public boolean isMasterSecretValid(Socket socket) {
-            return true;
-        }
-
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ssl/privileged/PrivilegedMasterSecretValidator.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/privileged/PrivilegedMasterSecretValidator.java
--- ./src/main/java/com/amazonaws/http/conn/ssl/privileged/PrivilegedMasterSecretValidator.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/privileged/PrivilegedMasterSecretValidator.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,105 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.conn.ssl.privileged;
-
-import java.lang.reflect.Method;
-import java.net.Socket;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.http.conn.ssl.MasterSecretValidators.MasterSecretValidator;
-
-/**
- * Implementation of {@link MasterSecretValidator} that verifies the master secret is non null
- * through use of Sun internal APIs. This validation is done only for JVMs affected by the SKIP-TLS
- * bug. It is best effort and any exception encountered while trying to validate the master secret
- * (including {@link SecurityException}) will be ignored
- */
-public class PrivilegedMasterSecretValidator implements MasterSecretValidator {
-
-    private static final Log LOG = LogFactory.getLog(PrivilegedMasterSecretValidator.class);
-
-    /**
-     * Double check the master secret of an SSL session is not null
-     * 
-     * @param socket
-     *            connected socket
-     * @return True if master secret is valid (i.e. non-null) or master secret cannot be validated,
-     *         false otherwise
-     */
-    public boolean isMasterSecretValid(final Socket socket) {
-        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-            @Override
-            public Boolean run() {
-                return privilegedIsMasterSecretValid(socket);
-            }
-        });
-    }
-
-    /**
-     * Checks the validity of an SSLSession's master secret. Should be run within a doPrivileged
-     * block
-     */
-    private boolean privilegedIsMasterSecretValid(final Socket socket) {
-        if (socket instanceof SSLSocket) {
-            SSLSession session = getSslSession(socket);
-            if (session != null) {
-                String className = session.getClass().getName();
-                if ("sun.security.ssl.SSLSessionImpl".equals(className)) {
-                    try {
-                        Object masterSecret = getMasterSecret(session, className);
-                        if (masterSecret == null) {
-                            session.invalidate();
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("Invalidated session " + session);
-                            }
-                            return false;
-                        }
-                    } catch (Exception e) {
-                        failedToVerifyMasterSecret(e);
-                    }
-                }
-            }
-        }
-        return true;
-
-    }
-
-    /**
-     * @return The active {@link SSLSession} for the Socket or null if there is none
-     */
-    private SSLSession getSslSession(final Socket socket) {
-        return ((SSLSocket) socket).getSession();
-    }
-
-    private Object getMasterSecret(SSLSession session, String className) throws Exception {
-        Class<?> clazz = Class.forName(className);
-        Method method = clazz.getDeclaredMethod("getMasterSecret");
-        method.setAccessible(true);
-        return method.invoke(session);
-    }
-
-    private void failedToVerifyMasterSecret(Throwable t) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Failed to verify the SSL master secret", t);
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ssl/SdkTLSSocketFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/SdkTLSSocketFactory.java
--- ./src/main/java/com/amazonaws/http/conn/ssl/SdkTLSSocketFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/SdkTLSSocketFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,189 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.http.conn.ssl;
-
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.internal.SdkMetricsSocket;
-import com.amazonaws.internal.SdkSSLMetricsSocket;
-import com.amazonaws.internal.SdkSSLSocket;
-import com.amazonaws.internal.SdkSocket;
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.util.JavaVersionParser;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.HttpHost;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.protocol.HttpContext;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLSocket;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.List;
-
-/**
- * Used to enforce the preferred TLS protocol during SSL handshake.
- */
-@ThreadSafe
-public class SdkTLSSocketFactory extends SSLConnectionSocketFactory {
-
-    private static final Log LOG = LogFactory.getLog(SdkTLSSocketFactory.class);
-    private final SSLContext sslContext;
-    private final MasterSecretValidators.MasterSecretValidator masterSecretValidator;
-    private final ShouldClearSslSessionPredicate shouldClearSslSessionsPredicate;
-
-    public SdkTLSSocketFactory(final SSLContext sslContext, final HostnameVerifier hostnameVerifier) {
-        super(sslContext, hostnameVerifier);
-        if (sslContext == null) {
-            throw new IllegalArgumentException(
-                    "sslContext must not be null. " + "Use SSLContext.getDefault() if you are unsure.");
-        }
-        this.sslContext = sslContext;
-        this.masterSecretValidator = MasterSecretValidators.getMasterSecretValidator();
-        this.shouldClearSslSessionsPredicate = new ShouldClearSslSessionPredicate(JavaVersionParser.getCurrentJavaVersion());
-    }
-
-    /**
-     * {@inheritDoc} Used to enforce the preferred TLS protocol during SSL handshake.
-     */
-    @Override
-    protected final void prepareSocket(final SSLSocket socket) {
-        String[] supported = socket.getSupportedProtocols();
-        String[] enabled = socket.getEnabledProtocols();
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("socket.getSupportedProtocols(): " + Arrays.toString(supported)
-                    + ", socket.getEnabledProtocols(): " + Arrays.toString(enabled));
-        }
-        List<String> target = new ArrayList<String>();
-        if (supported != null) {
-            // Append the preferred protocols in descending order of preference
-            // but only do so if the protocols are supported
-            TLSProtocol[] values = TLSProtocol.values();
-            for (int i = 0; i < values.length; i++) {
-                final String pname = values[i].getProtocolName();
-                if (existsIn(pname, supported)) {
-                    target.add(pname);
-                }
-            }
-        }
-        if (enabled != null) {
-            // Append the rest of the already enabled protocols to the end
-            // if not already included in the list
-            for (String pname : enabled) {
-                if (!target.contains(pname)) {
-                    target.add(pname);
-                }
-            }
-        }
-        if (target.size() > 0) {
-            String[] enabling = target.toArray(new String[target.size()]);
-            socket.setEnabledProtocols(enabling);
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("TLS protocol enabled for SSL handshake: " + Arrays.toString(enabling));
-            }
-        }
-    }
-
-    /**
-     * Returns true if the given element exists in the given array; false otherwise.
-     */
-    private boolean existsIn(String element, String[] a) {
-        for (String s : a) {
-            if (element.equals(s)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public Socket connectSocket(
-            final int connectTimeout,
-            final Socket socket,
-            final HttpHost host,
-            final InetSocketAddress remoteAddress,
-            final InetSocketAddress localAddress,
-            final HttpContext context) throws IOException {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("connecting to " + remoteAddress.getAddress() + ":" + remoteAddress.getPort());
-        }
-        Socket connectedSocket;
-        try {
-            connectedSocket = super.connectSocket
-                    (connectTimeout, socket, host, remoteAddress, localAddress, context);
-            if (!masterSecretValidator.isMasterSecretValid(connectedSocket)) {
-                throw log(new IllegalStateException("Invalid SSL master secret"));
-            }
-        } catch (final SSLException sslEx) {
-            if (shouldClearSslSessionsPredicate.test(sslEx)) {
-                // clear any related sessions from our cache
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("connection failed due to SSL error, clearing TLS session cache", sslEx);
-                }
-                clearSessionCache(sslContext.getClientSessionContext(), remoteAddress);
-            }
-            throw sslEx;
-        }
-
-        if (connectedSocket instanceof SSLSocket) {
-            SdkSSLSocket sslSocket = new SdkSSLSocket((SSLSocket) connectedSocket);
-            return AwsSdkMetrics.isHttpSocketReadMetricEnabled() ? new SdkSSLMetricsSocket(sslSocket) : sslSocket;
-        }
-        SdkSocket sdkSocket = new SdkSocket(connectedSocket);
-        return AwsSdkMetrics.isHttpSocketReadMetricEnabled() ? new SdkMetricsSocket(sdkSocket) : sdkSocket;
-    }
-
-    /**
-     * Invalidates all SSL/TLS sessions in {@code sessionContext} associated with {@code remoteAddress}.
-     *
-     * @param sessionContext collection of SSL/TLS sessions to be (potentially) invalidated
-     * @param remoteAddress  associated with sessions to invalidate
-     */
-    private void clearSessionCache(final SSLSessionContext sessionContext, final InetSocketAddress remoteAddress) {
-        final String hostName = remoteAddress.getHostName();
-        final int port = remoteAddress.getPort();
-        final Enumeration<byte[]> ids = sessionContext.getIds();
-
-        if (ids == null) {
-            return;
-        }
-
-        while (ids.hasMoreElements()) {
-            final byte[] id = ids.nextElement();
-            final SSLSession session = sessionContext.getSession(id);
-            if (session != null && session.getPeerHost() != null && session.getPeerHost().equalsIgnoreCase(hostName)
-                    && session.getPeerPort() == port) {
-                session.invalidate();
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Invalidated session " + session);
-                }
-            }
-        }
-    }
-
-    private <T extends Throwable> T log(T t) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("", t);
-        }
-        return t;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ssl/ShouldClearSslSessionPredicate.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/ShouldClearSslSessionPredicate.java
--- ./src/main/java/com/amazonaws/http/conn/ssl/ShouldClearSslSessionPredicate.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/ShouldClearSslSessionPredicate.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.http.conn.ssl;
-
-import com.amazonaws.internal.SdkPredicate;
-import com.amazonaws.util.JavaVersionParser.JavaVersion;
-
-import javax.net.ssl.SSLException;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Determines whether we should apply the workaround to bug that causes the SSL session cache to be
- * stuck in a bad state for either 24 hours or the next JVM restart. The workaround is to clear out
- * SSL sessions upon receiving an SSL exception. Whether we apply the workaround depends on the type
- * of SSL exception thrown and the JVM version in use.
- * 
- * @see <a href="http://tiny/1jjdylxma/wamazindeJava">http://tiny/1jjdylxma/wamazindeJava</a>
- */
-public class ShouldClearSslSessionPredicate extends SdkPredicate<SSLException> {
-
-    /**
-     * Fixed per http://bugs.java.com/view_bug.do?bug_id=8075750
-     */
-    public static final JavaVersion FIXED_JAVA_7 = new JavaVersion(1, 7, 0, 85);
-
-    /**
-     * Fixed per http://bugs.java.com/view_bug.do?bug_id=8074944
-     */
-    public static final JavaVersion FIXED_JAVA_8 = new JavaVersion(1, 8, 0, 60);
-
-    /**
-     * Message that may indicate the SSL session cache is in a bad state and needs to be cleared.
-     */
-    private static List<String> EXCEPTION_MESSAGE_WHITELIST = Arrays.asList("server certificate change is restricted",
-            "peer not authenticated");
-
-    private final JavaVersion javaVersion;
-
-    /**
-     * @param javaVersion
-     *            Current JVM version
-     */
-    public ShouldClearSslSessionPredicate(JavaVersion javaVersion) {
-        this.javaVersion = javaVersion;
-    }
-
-    /**
-     * @param sslEx
-     *            SSLException thrown during connect
-     * @return True is the SSL session cache should be cleared, false otherwise.
-     */
-    @Override
-    public boolean test(SSLException sslEx) {
-        return isExceptionAffected(sslEx.getMessage()) && isJvmAffected();
-    }
-
-    /**
-     * @return True if the current JVM version is subject to the bug described above, false
-     *         otherwise.
-     */
-    private boolean isJvmAffected() {
-        switch (javaVersion.getKnownVersion()) {
-        case JAVA_6:
-            // Java 6 was not and will not be patched for this bug
-            return true;
-        case JAVA_7:
-            return javaVersion.compareTo(FIXED_JAVA_7) < 0;
-        case JAVA_8:
-            return javaVersion.compareTo(FIXED_JAVA_8) < 0;
-        case JAVA_9:
-            // No Java 9 version is affected
-            return false;
-        case UNKNOWN:
-            // If we can't determine the Java version err on the side of caution and apply the fix
-            return true;
-        }
-        return true;
-    }
-
-    /**
-     * Restrict the workaround to only certain types of SSLExceptions that indicate the bug may have
-     * been encountered.
-     * 
-     * @param exceptionMessage
-     *            Message of the {@link SSLException}
-     * @return True if message indicates the bug may have been encountered, false otherwise
-     */
-    private boolean isExceptionAffected(final String exceptionMessage) {
-        if (exceptionMessage != null) {
-            for (String affectedMessage : EXCEPTION_MESSAGE_WHITELIST) {
-                if (exceptionMessage.contains(affectedMessage)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/ssl/TLSProtocol.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/TLSProtocol.java
--- ./src/main/java/com/amazonaws/http/conn/ssl/TLSProtocol.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/ssl/TLSProtocol.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.http.conn.ssl;
-
-/**
- * TLS protocols arranged in descending order of security preference in terms of
- * their ordinal numbers. See <a href=
- * "http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#jssenames"
- * >JSSE Standard Names</a>.
- */
-enum TLSProtocol {
-    TLSv1_2("TLSv1.2"), // most secure/preferred
-    TLSv1_1("TLSv1.1"),
-    TLSv1("TLSv1"),
-    TLS("TLS"),         // least secure/preferred, but acceptable
-    ;
-    private final String protocolName;
-
-    private TLSProtocol(String protocolName) {
-        this.protocolName = protocolName;
-    }
-
-    /**
-     * Returns the corresponding TLS protocol name as per the <a href=
-     * "http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#jssenames"
-     * >JSSE Standard Names</a>
-     */
-    String getProtocolName() {
-        return protocolName;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/conn/Wrapped.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/Wrapped.java
--- ./src/main/java/com/amazonaws/http/conn/Wrapped.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/conn/Wrapped.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,20 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.conn;
-
-/**
- * An internal marker interface to defend against accidental recursive wrappings.
- */
-interface Wrapped {}
diff -Nau8r ./src/main/java/com/amazonaws/http/DefaultErrorResponseHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/DefaultErrorResponseHandler.java
--- ./src/main/java/com/amazonaws/http/DefaultErrorResponseHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/DefaultErrorResponseHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,159 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.transform.Unmarshaller;
-import com.amazonaws.util.IOUtils;
-import com.amazonaws.util.StringUtils;
-import com.amazonaws.util.XpathUtils;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import static com.amazonaws.http.AmazonHttpClient.HEADER_SDK_TRANSACTION_ID;
-
-/**
- * Implementation of HttpResponseHandler that handles only error responses from Amazon Web Services.
- * A list of unmarshallers is passed into the constructor, and while handling a response, each
- * unmarshaller is tried, in order, until one is found that can successfully unmarshall the error
- * response.  If no unmarshaller is found that can unmarshall the error response, a generic
- * AmazonServiceException is created and populated with the AWS error response information (error
- * message, AWS error code, AWS request ID, etc).
- */
-@SdkProtectedApi
-public class DefaultErrorResponseHandler implements HttpResponseHandler<AmazonServiceException> {
-    private static final Log log = LogFactory.getLog(DefaultErrorResponseHandler.class);
-
-    /**
-     * The list of error response unmarshallers to try to apply to error responses.
-     */
-    private List<Unmarshaller<AmazonServiceException, Node>> unmarshallerList;
-
-    /**
-     * Constructs a new DefaultErrorResponseHandler that will handle error responses from Amazon
-     * services using the specified list of unmarshallers. Each unmarshaller will be tried, in
-     * order, until one is found that can unmarshall the error response.
-     *
-     * @param unmarshallerList The list of unmarshallers to try using when handling an error
-     *                         response.
-     */
-    public DefaultErrorResponseHandler(
-            List<Unmarshaller<AmazonServiceException, Node>> unmarshallerList) {
-        this.unmarshallerList = unmarshallerList;
-    }
-
-    @Override
-    public AmazonServiceException handle(HttpResponse errorResponse) throws Exception {
-        AmazonServiceException ase = createAse(errorResponse);
-        if (ase == null) {
-            throw new SdkClientException("Unable to unmarshall error response from service");
-        }
-        ase.setHttpHeaders(errorResponse.getHeaders());
-        if (StringUtils.isNullOrEmpty(ase.getErrorCode())) {
-            ase.setErrorCode(errorResponse.getStatusCode() + " " + errorResponse.getStatusText());
-        }
-        return ase;
-    }
-
-    private AmazonServiceException createAse(HttpResponse errorResponse) throws Exception {
-        // Try to parse the error response as XML
-        final Document document = documentFromContent(errorResponse.getContent(), idString(errorResponse));
-
-        /*
-         * We need to select which exception unmarshaller is the correct one to
-         * use from all the possible exceptions this operation can throw.
-         * Currently we rely on the unmarshallers to return null if they can't
-         * unmarshall the response, but we might need something a little more
-         * sophisticated in the future.
-         */
-        for (Unmarshaller<AmazonServiceException, Node> unmarshaller : unmarshallerList) {
-            AmazonServiceException ase = unmarshaller.unmarshall(document);
-            if (ase != null) {
-                ase.setStatusCode(errorResponse.getStatusCode());
-                return ase;
-            }
-        }
-        return null;
-    }
-
-    private Document documentFromContent(InputStream content, String idString) throws ParserConfigurationException, SAXException, IOException {
-        try {
-            return parseXml(contentToString(content, idString), idString);
-        } catch (Exception e) {
-            // Generate an empty document to make the unmarshallers happy. Ultimately the default
-            // unmarshaller will be called to unmarshall into the service base exception.
-            return XpathUtils.documentFrom("<empty/>");
-        }
-    }
-
-    private String contentToString(InputStream content, String idString) throws Exception {
-        try {
-            return IOUtils.toString(content);
-        } catch (Exception e) {
-            log.debug(String.format("Unable to read input stream to string (%s)", idString), e);
-            throw e;
-        }
-    }
-
-    private Document parseXml(String xml, String idString) throws Exception {
-        try {
-            return XpathUtils.documentFrom(xml);
-        } catch (Exception e) {
-            log.debug(String.format("Unable to parse HTTP response (%s) content to XML document '%s' ", idString, xml), e);
-            throw e;
-        }
-    }
-
-    private String idString(HttpResponse errorResponse) {
-        StringBuilder idString = new StringBuilder();
-        try {
-            if (errorResponse.getRequest().getHeaders().containsKey(HEADER_SDK_TRANSACTION_ID)) {
-                idString.append("Invocation Id:").append(errorResponse.getRequest().getHeaders().get(HEADER_SDK_TRANSACTION_ID));
-            }
-            if (errorResponse.getHeaders().containsKey(X_AMZN_REQUEST_ID_HEADER)) {
-                if (idString.length() > 0) {
-                    idString.append(", ");
-                }
-                idString.append("Request Id:").append(errorResponse.getHeaders().get(X_AMZN_REQUEST_ID_HEADER));
-            }
-        } catch (NullPointerException npe){
-            log.debug("Error getting Request or Invocation ID from response", npe);
-        }
-        return idString.length() > 0 ? idString.toString() : "Unknown";
-    }
-
-    /**
-     * Since this response handler completely consumes all the data from the underlying HTTP
-     * connection during the handle method, we don't need to keep the HTTP connection open.
-     *
-     * @see com.amazonaws.http.HttpResponseHandler#needsConnectionLeftOpen()
-     */
-    public boolean needsConnectionLeftOpen() {
-        return false;
-    }
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/DelegatingDnsResolver.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/DelegatingDnsResolver.java
--- ./src/main/java/com/amazonaws/http/DelegatingDnsResolver.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/DelegatingDnsResolver.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,40 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-import org.apache.http.conn.DnsResolver;
-
-/**
- * Implements the {@link org.apache.http.conn.DnsResolver} interface,
- * taking in a {@link com.amazonaws.DnsResolver} implementation and executing its
- * {@link com.amazonaws.DnsResolver#resolve(String)} method to perform the
- * actual DNS resolution.
- */
-public class DelegatingDnsResolver implements DnsResolver {
-
-    private final com.amazonaws.DnsResolver delegate;
-
-    public DelegatingDnsResolver(com.amazonaws.DnsResolver delegate) {
-        this.delegate = delegate;
-    }
-
-    @Override
-    public InetAddress[] resolve(String host) throws UnknownHostException {
-        return delegate.resolve(host);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/exception/HttpRequestTimeoutException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/exception/HttpRequestTimeoutException.java
--- ./src/main/java/com/amazonaws/http/exception/HttpRequestTimeoutException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/exception/HttpRequestTimeoutException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.exception;
-
-import java.io.IOException;
-
-/**
- * Signals that the http request could not complete within the specified timeout.
- */
-public class HttpRequestTimeoutException extends IOException {
-
-    private static final long serialVersionUID = -2588353895012259837L;
-
-    public HttpRequestTimeoutException(String message) {
-        super(message);
-    }
-
-    public HttpRequestTimeoutException(Throwable throwable) {
-        this("Request did not complete before the request timeout configuration.", throwable);
-    }
-
-    public HttpRequestTimeoutException(String message, Throwable throwable) {
-        super(message, throwable);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/ExecutionContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/ExecutionContext.java
--- ./src/main/java/com/amazonaws/http/ExecutionContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/ExecutionContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,267 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.AmazonWebServiceClient;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.Signer;
-import com.amazonaws.handlers.RequestHandler2;
-import com.amazonaws.http.timers.client.ClientExecutionAbortTrackerTask;
-import com.amazonaws.internal.auth.NoOpSignerProvider;
-import com.amazonaws.internal.auth.SignerProviderContext;
-import com.amazonaws.internal.auth.SignerProvider;
-import com.amazonaws.retry.internal.AuthErrorRetryStrategy;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.AWSRequestMetricsFullSupport;
-
-import java.net.URI;
-import java.util.List;
-
-/**
- * @NotThreadSafe This class should only be accessed by a single thread and be used throughout
- *                a single request lifecycle.
- */
-@NotThreadSafe
-public class ExecutionContext {
-    private final AWSRequestMetrics awsRequestMetrics;
-    private final List<RequestHandler2> requestHandler2s;
-    private final AmazonWebServiceClient awsClient;
-    private final SignerProvider signerProvider;
-
-    private boolean retryCapacityConsumed;
-
-    /**
-     * Optional credentials to enable the runtime layer to handle signing requests (and resigning on
-     * retries).
-     */
-    private AWSCredentialsProvider credentialsProvider;
-
-    /**
-     * An internal retry strategy for auth errors. This is currently only used by the S3 client for
-     * auto-resolving V4-required regions.
-     */
-    private AuthErrorRetryStrategy authErrorRetryStrategy;
-
-    private ClientExecutionAbortTrackerTask clientExecutionTrackerTask;
-
-    /** For testing purposes. */
-    public ExecutionContext(boolean isMetricEnabled) {
-        this(builder().withUseRequestMetrics(isMetricEnabled).withSignerProvider(new NoOpSignerProvider()));
-    }
-
-    /** For testing purposes. */
-    public ExecutionContext() {
-        this(builder().withSignerProvider(new NoOpSignerProvider()));
-    }
-
-    @Deprecated
-    public ExecutionContext(List<RequestHandler2> requestHandler2s, boolean isMetricEnabled,
-            AmazonWebServiceClient awsClient) {
-        this.requestHandler2s = requestHandler2s;
-        awsRequestMetrics = isMetricEnabled ? new AWSRequestMetricsFullSupport() : new AWSRequestMetrics();
-        this.awsClient = awsClient;
-        this.signerProvider = new SignerProvider() {
-            @Override
-            public Signer getSigner(SignerProviderContext context) {
-                return getSignerByURI(context.getUri());
-            }
-        };
-    }
-
-    private ExecutionContext(final Builder builder) {
-        this.requestHandler2s = builder.requestHandler2s;
-        this.awsRequestMetrics = builder.useRequestMetrics ? new AWSRequestMetricsFullSupport() : new AWSRequestMetrics();
-        this.awsClient = builder.awsClient;
-        this.signerProvider = builder.signerProvider;
-    }
-
-    public List<RequestHandler2> getRequestHandler2s() {
-        return requestHandler2s;
-    }
-
-    public AWSRequestMetrics getAwsRequestMetrics() {
-        return awsRequestMetrics;
-    }
-
-    protected AmazonWebServiceClient getAwsClient() {
-        return awsClient;
-    }
-
-    /**
-     * There is in general no need to set the signer in the execution context, since the signer for
-     * each request may differ depending on the URI of the request. The exception is S3 where the
-     * signer is currently determined only when the S3 client is constructed. Hence the need for
-     * this method. We may consider supporting a per request level signer determination for S3 later
-     * on.
-     */
-    @Deprecated
-    public void setSigner(Signer signer) {
-    }
-
-    /**
-     * Returns whether retry capacity was consumed during this request lifecycle.
-     * This can be inspected to determine whether capacity should be released if a retry succeeds.
-     *
-     * @return true if retry capacity was consumed
-     */
-    public boolean retryCapacityConsumed() { return retryCapacityConsumed; }
-
-    /**
-     * Marks that a retry during this request lifecycle has consumed retry capacity.  This is inspected
-     * when determining if capacity should be released if a retry succeeds.
-     */
-    public void markRetryCapacityConsumed() {
-        this.retryCapacityConsumed = true;
-    }
-
-    /**
-     * Passes in the provided {@link SignerProviderContext} into a {@link SignerProvider} and returns
-     * a {@link Signer} instance.
-     */
-    public Signer getSigner(SignerProviderContext context) { return signerProvider.getSigner(context); }
-
-    /**
-     * Returns the signer for the given uri. Note S3 in particular overrides this method.
-     */
-    @Deprecated
-    public Signer getSignerByURI(URI uri) {
-        return awsClient == null ? null : awsClient.getSignerByURI(uri);
-    }
-
-    /**
-     * Sets the credentials provider used for fetching the credentials. The credentials fetched is
-     * used for signing the request. If there is no credential provider, then the runtime will not
-     * attempt to sign (or resign on retries) requests.
-     *
-     * @param credentialsProvider
-     *            the credentials provider to fetch {@link AWSCredentials}
-     */
-    public void setCredentialsProvider(AWSCredentialsProvider credentialsProvider) {
-        this.credentialsProvider = credentialsProvider;
-    }
-
-    /**
-     * Returns the credentials provider used for fetching the credentials. The credentials fetched
-     * is used for signing the request. If there is no credential provider, then the runtime will
-     * not attempt to sign (or resign on retries) requests.
-     *
-     * @return the credentials provider to fetch {@link AWSCredentials}
-     */
-    public AWSCredentialsProvider getCredentialsProvider() {
-        return this.credentialsProvider;
-    }
-
-    /**
-     * Returns the retry strategy for auth errors. This is currently only used by the S3 client for
-     * auto-resolving sigv4-required regions.
-     * <p>
-     * Note that this will be checked BEFORE the HTTP client consults the user-specified
-     * RetryPolicy. i.e. if the configured AuthErrorRetryStrategy says the request should be
-     * retried, the retry will be performed internally and the effect is transparent to the user's
-     * RetryPolicy.
-     */
-    public AuthErrorRetryStrategy getAuthErrorRetryStrategy() {
-        return authErrorRetryStrategy;
-    }
-
-    /**
-     * Sets the optional auth error retry strategy for this request execution.
-     *
-     * @see #getAuthErrorRetryStrategy()
-     */
-    public void setAuthErrorRetryStrategy(AuthErrorRetryStrategy authErrorRetryStrategy) {
-        this.authErrorRetryStrategy = authErrorRetryStrategy;
-    }
-
-    public ClientExecutionAbortTrackerTask getClientExecutionTrackerTask() {
-        return clientExecutionTrackerTask;
-    }
-
-    public void setClientExecutionTrackerTask(ClientExecutionAbortTrackerTask clientExecutionTrackerTask) {
-        this.clientExecutionTrackerTask = clientExecutionTrackerTask;
-    }
-
-    public static ExecutionContext.Builder builder() { return new ExecutionContext.Builder(); }
-
-    public static class Builder {
-
-        private boolean useRequestMetrics;
-        private List<RequestHandler2> requestHandler2s;
-        private AmazonWebServiceClient awsClient;
-        private SignerProvider signerProvider = new NoOpSignerProvider();
-
-        private Builder() {}
-
-        public boolean useRequestMetrics() {
-            return useRequestMetrics;
-        }
-
-        public void setUseRequestMetrics(final boolean useRequestMetrics) {
-            this.useRequestMetrics = useRequestMetrics;
-        }
-
-        public Builder withUseRequestMetrics(final boolean withUseRequestMetrics) {
-            setUseRequestMetrics(withUseRequestMetrics);
-            return this;
-        }
-
-        public List<RequestHandler2> getRequestHandler2s() {
-            return requestHandler2s;
-        }
-
-        public void setRequestHandler2s(final List<RequestHandler2> requestHandler2s) {
-            this.requestHandler2s = requestHandler2s;
-        }
-
-        public Builder withRequestHandler2s(final List<RequestHandler2> requestHandler2s) {
-            setRequestHandler2s(requestHandler2s);
-            return this;
-        }
-
-        public AmazonWebServiceClient getAwsClient() {
-            return awsClient;
-        }
-
-        public void setAwsClient(final AmazonWebServiceClient awsClient) {
-            this.awsClient = awsClient;
-        }
-
-        public Builder withAwsClient(final AmazonWebServiceClient awsClient) {
-            setAwsClient(awsClient);
-            return this;
-        }
-
-        public SignerProvider getSignerProvider() {
-            return signerProvider;
-        }
-
-        public void setSignerProvider(final SignerProvider signerProvider) {
-            this.signerProvider = signerProvider;
-        }
-
-        public Builder withSignerProvider(final SignerProvider signerProvider) {
-            setSignerProvider(signerProvider);
-            return this;
-        }
-
-        public ExecutionContext build() {
-            return new ExecutionContext(this);
-        }
-
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/HttpMethodName.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/HttpMethodName.java
--- ./src/main/java/com/amazonaws/http/HttpMethodName.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/HttpMethodName.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.util.StringUtils;
-
-public enum HttpMethodName {
-
-    GET,
-    POST,
-    PUT,
-    DELETE,
-    HEAD,
-    PATCH,
-    OPTIONS,
-    ;
-
-    /**
-     * @param value Raw string representing value of enum
-     * @return HttpMethodName enum or null if value is not present.
-     * @throws IllegalArgumentException If value does not represent a known enum value.
-     */
-    public static HttpMethodName fromValue(String value) {
-        if (StringUtils.isNullOrEmpty(value)) {
-            return null;
-        }
-
-        final String upperCaseValue = StringUtils.upperCase(value);
-        for (HttpMethodName httpMethodName : values()) {
-            if (httpMethodName.name().equals(upperCaseValue)) {
-                return httpMethodName;
-            }
-        }
-        throw new IllegalArgumentException("Unsupported HTTP method name " + value);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/HttpResponseHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/HttpResponseHandler.java
--- ./src/main/java/com/amazonaws/http/HttpResponseHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/HttpResponseHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,66 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-/**
- * Responsible for handling an HTTP response and returning an object of type T.
- * For example, a typical response handler might accept a response, and
- * translate it into a concrete typed object.
- *
- * @param <T>
- *            The output of this response handler.
- */
-public interface HttpResponseHandler<T> {
-
-    String X_AMZN_REQUEST_ID_HEADER = "x-amzn-RequestId";
-
-    /**
-     * Accepts an HTTP response object, and returns an object of type T.
-     * Individual implementations may choose to handle the response however they
-     * need to, and return any type that they need to.
-     *
-     * @param response
-     *            The HTTP response to handle, as received from an AWS service.
-     *
-     * @return An object of type T, as defined by individual implementations.
-     *
-     * @throws Exception
-     *             If any problems are encountered handling the response.
-     */
-    T handle(HttpResponse response) throws Exception;
-
-    /**
-     * Indicates if this response handler requires that the underlying HTTP
-     * connection <b>not</b> be closed automatically after the response is
-     * handled.
-     * <p>
-     * For example, if the object returned by this response handler manually
-     * manages the stream of data from the HTTP connection, and doesn't read all
-     * the data from the connection in the {@link #handle(HttpResponse)} method,
-     * this method can be used to prevent the underlying connection from being
-     * prematurely closed.
-     * <p>
-     * Response handlers should use this option very carefully, since it means
-     * that resource cleanup is no longer handled automatically, and if
-     * neglected, can result in the client runtime running out of resources for
-     * new HTTP connections.
-     *
-     * @return True if this response handler requires that the underlying HTTP
-     *         connection be left open, and not automatically closed, otherwise
-     *         false.
-     */
-    boolean needsConnectionLeftOpen();
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/HttpResponse.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/HttpResponse.java
--- ./src/main/java/com/amazonaws/http/HttpResponse.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/HttpResponse.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,185 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.Request;
-import com.amazonaws.util.CRC32ChecksumCalculatingInputStream;
-
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.protocol.HttpContext;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Represents an HTTP response returned by an AWS service in response to a
- * service request.
- */
-public class HttpResponse {
-
-    private final Request<?> request;
-    private final HttpRequestBase httpRequest;
-
-    private String statusText;
-    private int statusCode;
-    private InputStream content;
-    private Map<String, String> headers = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
-    private HttpContext context;
-
-    /**
-     * Constructs a new HttpResponse associated with the specified request.
-     *
-     * @param request
-     *            The associated request that generated this response.
-     * @param httpRequest
-     *            The underlying http request that generated this response.
-     * @throws IOException
-     */
-    public HttpResponse(Request<?> request, HttpRequestBase httpRequest) {
-        this(request, httpRequest, null);
-    }
-
-    public HttpResponse(Request<?> request, HttpRequestBase httpRequest, HttpContext context) {
-        this.request = request;
-        this.httpRequest = httpRequest;
-        this.context = context;
-    }
-
-    /**
-     * Returns the original request associated with this response.
-     *
-     * @return The original request associated with this response.
-     */
-    public Request<?> getRequest() {
-        return request;
-    }
-
-    /**
-     * Returns the original http request associated with this response.
-     *
-     * @return The original http request associated with this response.
-     */
-    public HttpRequestBase getHttpRequest() {
-        return httpRequest;
-    }
-
-    /**
-     * Returns the HTTP headers returned with this response.
-     *
-     * @return The set of HTTP headers returned with this HTTP response.
-     */
-    public Map<String, String> getHeaders() {
-        return headers;
-    }
-
-    /**
-     * Looks up a header by name and returns its value. Does case insensitive comparison.
-     *
-     * @param headerName Name of header to get value for.
-     * @return The header value of the given header. Null if header is not present.
-     */
-    public String getHeader(String headerName) {
-        return headers.get(headerName);
-    }
-
-    /**
-     * Adds an HTTP header to the set associated with this response.
-     *
-     * @param name
-     *            The name of the HTTP header.
-     * @param value
-     *            The value of the HTTP header.
-     */
-    public void addHeader(String name, String value) {
-        headers.put(name, value);
-    }
-
-    /**
-     * Sets the input stream containing the response content.
-     *
-     * @param content
-     *            The input stream containing the response content.
-     */
-    public void setContent(InputStream content) {
-        this.content = content;
-    }
-
-    /**
-     * Returns the input stream containing the response content.
-     *
-     * @return The input stream containing the response content.
-     */
-    public InputStream getContent() {
-        return content;
-    }
-
-    /**
-     * Sets the HTTP status text returned with this response.
-     *
-     * @param statusText
-     *            The HTTP status text (ex: "Not found") returned with this
-     *            response.
-     */
-    public void setStatusText(String statusText) {
-        this.statusText = statusText;
-    }
-
-    /**
-     * Returns the HTTP status text associated with this response.
-     *
-     * @return The HTTP status text associated with this response.
-     */
-    public String getStatusText() {
-        return statusText;
-    }
-
-    /**
-     * Sets the HTTP status code that was returned with this response.
-     *
-     * @param statusCode
-     *            The HTTP status code (ex: 200, 404, etc) associated with this
-     *            response.
-     */
-    public void setStatusCode(int statusCode) {
-        this.statusCode = statusCode;
-    }
-
-    /**
-     * Returns the HTTP status code (ex: 200, 404, etc) associated with this
-     * response.
-     *
-     * @return The HTTP status code associated with this response.
-     */
-    public int getStatusCode() {
-        return statusCode;
-    }
-
-    /**
-     * Returns the CRC32 checksum calculated by the underlying CRC32ChecksumCalculatingInputStream.
-     *
-     * @return The CRC32 checksum.
-     */
-    public long getCRC32Checksum() {
-        if (context == null) {
-            return 0L;
-        }
-        CRC32ChecksumCalculatingInputStream crc32ChecksumInputStream =
-                (CRC32ChecksumCalculatingInputStream)context.getAttribute(CRC32ChecksumCalculatingInputStream.class.getName());
-        return crc32ChecksumInputStream == null ? 0L : crc32ChecksumInputStream.getCRC32Checksum();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/IdleConnectionReaper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/IdleConnectionReaper.java
--- ./src/main/java/com/amazonaws/http/IdleConnectionReaper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/IdleConnectionReaper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,198 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.conn.HttpClientConnectionManager;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Daemon thread to periodically check connection pools for idle connections.
- * <p/>
- * Connections sitting around idle in the HTTP connection pool for too long will
- * eventually be terminated by the AWS end of the connection, and will go into
- * CLOSE_WAIT. If this happens, sockets will sit around in CLOSE_WAIT, still
- * using resources on the client side to manage that socket. Many sockets stuck
- * in CLOSE_WAIT can prevent the OS from creating new connections.
- * <p/>
- * This class closes idle connections before they can move into the CLOSE_WAIT
- * state.
- * <p/>
- * This thread is important because by default, we disable Apache HttpClient's
- * stale connection checking, so without this thread running in the background,
- * cleaning up old/inactive HTTP connections, we'd see more IO exceptions when
- * stale connections (i.e. closed on the AWS side) are left in the connection
- * pool, and requests grab one of them to begin executing a request.
- */
-@SdkInternalApi
-public final class IdleConnectionReaper extends Thread {
-
-    /**
-     * Shared log for any errors during connection reaping.
-     */
-    private static final Log LOG = LogFactory.getLog(IdleConnectionReaper.class);
-    /**
-     * The period between invocations of the idle connection reaper.
-     */
-    private static final int PERIOD_MILLISECONDS = 1000 * 60;
-
-    /**
-     * Legacy constant used when {@link #registerConnectionManager(HttpClientConnectionManager)} is called. New code paths should
-     * use {@link #registerConnectionManager(HttpClientConnectionManager, long)} and provide the max idle timeout for that
-     * particular connection manager.
-     */
-    @Deprecated
-    private static final int DEFAULT_MAX_IDLE_MILLIS = 1000 * 60;
-
-    private static final Map<HttpClientConnectionManager, Long> connectionManagers = new ConcurrentHashMap<HttpClientConnectionManager, Long>();
-    /**
-     * Singleton instance of the connection reaper.
-     */
-    private static volatile IdleConnectionReaper instance;
-    /**
-     * Set to true when shutting down the reaper;  Once set to true, this
-     * flag is never set back to false.
-     */
-    private volatile boolean shuttingDown;
-
-    /**
-     * Private constructor - singleton pattern.
-     */
-    private IdleConnectionReaper() {
-        super("java-sdk-http-connection-reaper");
-        setDaemon(true);
-    }
-
-    /**
-     * Registers the given connection manager with this reaper.
-     *
-     * @return true if the connection manager has been successfully registered; false otherwise.
-     * @deprecated By {@link #registerConnectionManager(HttpClientConnectionManager, long)}.
-     */
-    @Deprecated
-    public static boolean registerConnectionManager(HttpClientConnectionManager connectionManager) {
-        return registerConnectionManager(connectionManager, DEFAULT_MAX_IDLE_MILLIS);
-    }
-
-    /**
-     * Registers the given connection manager with this reaper;
-     *
-     * @param connectionManager Connection manager to register
-     * @param maxIdleInMs       Max idle connection timeout in milliseconds for this connection manager.
-     * @return true if the connection manager has been successfully registered; false otherwise.
-     */
-    public static boolean registerConnectionManager(HttpClientConnectionManager connectionManager, long maxIdleInMs) {
-        if (instance == null) {
-            synchronized (IdleConnectionReaper.class) {
-                if (instance == null) {
-                    instance = new IdleConnectionReaper();
-                    instance.start();
-                }
-            }
-        }
-        return connectionManagers.put(connectionManager, maxIdleInMs) == null;
-    }
-
-    /**
-     * Removes the given connection manager from this reaper,
-     * and shutting down the reaper if there is zero connection manager left.
-     *
-     * @return true if the connection manager has been successfully removed;
-     * false otherwise.
-     */
-    public static boolean removeConnectionManager(HttpClientConnectionManager connectionManager) {
-        boolean wasRemoved = connectionManagers.remove(connectionManager) != null;
-        if (connectionManagers.isEmpty()) {
-            shutdown();
-        }
-        return wasRemoved;
-    }
-
-    @SdkTestInternalApi
-    public static List<HttpClientConnectionManager> getRegisteredConnectionManagers() {
-        return new ArrayList<HttpClientConnectionManager>(connectionManagers.keySet());
-    }
-
-    /**
-     * Shuts down the thread, allowing the class and instance to be collected.
-     * <p/>
-     * Since this is a daemon thread, its running will not prevent JVM shutdown.
-     * It will, however, prevent this class from being unloaded or garbage
-     * collected, in the context of a long-running application, until it is
-     * interrupted. This method will stop the thread's execution and clear its
-     * state. Any use of a service client will cause the thread to be restarted.
-     *
-     * @return true if an actual shutdown has been made; false otherwise.
-     */
-    public static synchronized boolean shutdown() {
-        if (instance != null) {
-            instance.markShuttingDown();
-            instance.interrupt();
-            connectionManagers.clear();
-            instance = null;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * For testing purposes.
-     * Returns the number of connection managers currently monitored by this
-     * reaper.
-     */
-    static int size() {
-        return connectionManagers.size();
-    }
-
-    private void markShuttingDown() {
-        shuttingDown = true;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void run() {
-        while (true) {
-            if (shuttingDown) {
-                LOG.debug("Shutting down reaper thread.");
-                return;
-            }
-            try {
-                Thread.sleep(PERIOD_MILLISECONDS);
-
-                for (Map.Entry<HttpClientConnectionManager, Long> entry : connectionManagers.entrySet()) {
-                    // When we release connections, the connection manager leaves them
-                    // open so they can be reused.  We want to close out any idle
-                    // connections so that they don't sit around in CLOSE_WAIT.
-                    try {
-                        entry.getKey().closeIdleConnections(entry.getValue(), TimeUnit.MILLISECONDS);
-                    } catch (Exception t) {
-                        LOG.warn("Unable to close idle connections", t);
-                    }
-                }
-            } catch (Throwable t) {
-                LOG.debug("Reaper thread: ", t);
-            }
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/impl/client/HttpRequestNoRetryHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/impl/client/HttpRequestNoRetryHandler.java
--- ./src/main/java/com/amazonaws/http/impl/client/HttpRequestNoRetryHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/impl/client/HttpRequestNoRetryHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,35 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.impl.client;
-
-import com.amazonaws.annotation.ThreadSafe;
-
-import java.io.IOException;
-
-import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
-import org.apache.http.protocol.HttpContext;
-
-@ThreadSafe
-public class HttpRequestNoRetryHandler extends DefaultHttpRequestRetryHandler {
-    public static final HttpRequestNoRetryHandler Singleton = new HttpRequestNoRetryHandler();
-    private HttpRequestNoRetryHandler() {}
-
-    @Override public boolean retryRequest(
-            final IOException exception,
-            int executionCount,
-            final HttpContext context) {
-        return false;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/impl/client/SdkHttpRequestRetryHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/impl/client/SdkHttpRequestRetryHandler.java
--- ./src/main/java/com/amazonaws/http/impl/client/SdkHttpRequestRetryHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/impl/client/SdkHttpRequestRetryHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.impl.client;
-
-import java.io.IOException;
-
-import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
-import org.apache.http.protocol.HttpContext;
-
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.AWSRequestMetrics.Field;
-
-@ThreadSafe
-public class SdkHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
-    public static final SdkHttpRequestRetryHandler Singleton = new SdkHttpRequestRetryHandler();
-    private SdkHttpRequestRetryHandler() {}
-
-    @Override public boolean retryRequest(
-            final IOException exception,
-            int executionCount,
-            final HttpContext context) {
-        boolean retry = super.retryRequest(exception, executionCount, context);
-        if (retry) {
-            AWSRequestMetrics awsRequestMetrics = (AWSRequestMetrics) context
-                    .getAttribute(AWSRequestMetrics.SIMPLE_NAME);
-            if (awsRequestMetrics != null) {
-                awsRequestMetrics.incrementCounter(Field.HttpClientRetryCount);
-            }
-        }
-        return retry;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/JsonErrorResponseHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/JsonErrorResponseHandler.java
--- ./src/main/java/com/amazonaws/http/JsonErrorResponseHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/JsonErrorResponseHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,131 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonServiceException.ErrorType;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.internal.http.ErrorCodeParser;
-import com.amazonaws.internal.http.JsonErrorMessageParser;
-import com.amazonaws.protocol.json.JsonContent;
-import com.amazonaws.transform.JsonErrorUnmarshaller;
-import com.fasterxml.jackson.core.JsonFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-@SdkInternalApi
-public class JsonErrorResponseHandler implements HttpResponseHandler<AmazonServiceException> {
-
-    private static final Log LOG = LogFactory.getLog(JsonErrorResponseHandler.class);
-
-    private final List<JsonErrorUnmarshaller> unmarshallers;
-    private final ErrorCodeParser errorCodeParser;
-    private final JsonErrorMessageParser errorMessageParser;
-    private final JsonFactory jsonFactory;
-
-    public JsonErrorResponseHandler(
-            List<JsonErrorUnmarshaller> errorUnmarshallers,
-            ErrorCodeParser errorCodeParser,
-            JsonErrorMessageParser errorMessageParser,
-            JsonFactory jsonFactory) {
-        this.unmarshallers = errorUnmarshallers;
-        this.errorCodeParser = errorCodeParser;
-        this.errorMessageParser = errorMessageParser;
-        this.jsonFactory = jsonFactory;
-    }
-
-    @Override
-    public boolean needsConnectionLeftOpen() {
-        return false;
-    }
-
-    @Override
-    public AmazonServiceException handle(HttpResponse response) throws Exception {
-        JsonContent jsonContent = JsonContent.createJsonContent(response, jsonFactory);
-        String errorCode = errorCodeParser.parseErrorCode(response, jsonContent);
-        AmazonServiceException ase = createException(errorCode, jsonContent);
-
-        // Jackson has special-casing for 'message' values when deserializing
-        // Throwables, but sometimes the service passes the error message in
-        // other JSON fields - handle it here.
-        if (ase.getErrorMessage() == null) {
-            ase.setErrorMessage(errorMessageParser.parseErrorMessage(response, jsonContent.getJsonNode()));
-        }
-
-        ase.setErrorCode(errorCode);
-        ase.setServiceName(response.getRequest().getServiceName());
-        ase.setStatusCode(response.getStatusCode());
-        ase.setErrorType(getErrorTypeFromStatusCode(response.getStatusCode()));
-        ase.setRawResponse(jsonContent.getRawContent());
-        String requestId = getRequestIdFromHeaders(response.getHeaders());
-        if (requestId != null) {
-            ase.setRequestId(requestId);
-        }
-        ase.setHttpHeaders(response.getHeaders());
-        return ase;
-    }
-
-    /**
-     * Create an AmazonServiceException using the chain of unmarshallers. This method will never
-     * return null, it will always return a valid AmazonServiceException
-     *
-     * @param errorCode
-     *            Error code to find an appropriate unmarshaller
-     * @param jsonContent
-     *            JsonContent of HTTP response
-     * @return AmazonServiceException
-     */
-    private AmazonServiceException createException(String errorCode, JsonContent jsonContent) {
-        AmazonServiceException ase = unmarshallException(errorCode, jsonContent);
-        if (ase == null) {
-            ase = new AmazonServiceException(
-                    "Unable to unmarshall exception response with the unmarshallers provided");
-        }
-        return ase;
-    }
-
-    private AmazonServiceException unmarshallException(String errorCode, JsonContent jsonContent) {
-        for (JsonErrorUnmarshaller unmarshaller : unmarshallers) {
-            if (unmarshaller.matchErrorCode(errorCode)) {
-                try {
-                    return unmarshaller.unmarshall(jsonContent.getJsonNode());
-                } catch (Exception e) {
-                    LOG.info("Unable to unmarshall exception content", e);
-                    return null;
-                }
-            }
-        }
-        return null;
-    }
-
-    private ErrorType getErrorTypeFromStatusCode(int statusCode) {
-        return statusCode < 500 ? ErrorType.Client : ErrorType.Service;
-    }
-
-    private String getRequestIdFromHeaders(Map<String, String> headers) {
-        for (Entry<String, String> headerEntry : headers.entrySet()) {
-            if (headerEntry.getKey().equalsIgnoreCase(X_AMZN_REQUEST_ID_HEADER)) {
-                return headerEntry.getValue();
-            }
-        }
-        return null;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/JsonResponseHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/JsonResponseHandler.java
--- ./src/main/java/com/amazonaws/http/JsonResponseHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/JsonResponseHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,178 +0,0 @@
-/*
- *
- * Copyright (c) 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-package com.amazonaws.http;
-
-import com.amazonaws.AmazonWebServiceResponse;
-import com.amazonaws.ResponseMetadata;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.internal.CRC32MismatchException;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.JsonUnmarshallerContext.UnmarshallerType;
-import com.amazonaws.transform.JsonUnmarshallerContextImpl;
-import com.amazonaws.transform.Unmarshaller;
-import com.amazonaws.transform.VoidJsonUnmarshaller;
-import com.amazonaws.util.IOUtils;
-import com.amazonaws.util.ValidationUtils;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonParser;
-import java.io.IOException;
-import java.util.Map;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Default implementation of HttpResponseHandler that handles a successful response from an AWS
- * service and unmarshalls the result using a JSON unmarshaller.
- *
- * @param <T> Indicates the type being unmarshalled by this response handler.
- */
-@SdkInternalApi
-public class JsonResponseHandler<T> implements HttpResponseHandler<AmazonWebServiceResponse<T>> {
-
-    /**
-     * The JSON unmarshaller to use when handling the response
-     */
-    private Unmarshaller<T, JsonUnmarshallerContext> responseUnmarshaller;
-
-    /**
-     * Shared logger for profiling information
-     */
-    private static final Log log = LogFactory.getLog("com.amazonaws.request");
-
-    private final JsonFactory jsonFactory;
-
-    private final boolean needsConnectionLeftOpen;
-
-    private final boolean isPayloadJson;
-
-    private final Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> simpleTypeUnmarshallers;
-    private final Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customTypeMarshallers;
-
-    /**
-     * Constructs a new response handler that will use the specified JSON unmarshaller to unmarshall
-     * the service response and uses the specified response element path to find the root of the
-     * business data in the service's response.
-     * @param responseUnmarshaller    The JSON unmarshaller to use on the response.
-     * @param simpleTypeUnmarshallers List of unmarshallers to be used for scalar types.
-     * @param customTypeMarshallers   List of custom unmarshallers to be used for special types.
-     * @param jsonFactory             the json factory to be used for parsing the response.
-     */
-    public JsonResponseHandler(Unmarshaller<T, JsonUnmarshallerContext> responseUnmarshaller,
-                               Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> simpleTypeUnmarshallers,
-                               Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customTypeMarshallers,
-                               JsonFactory jsonFactory, boolean needsConnectionLeftOpen,
-                               boolean isPayloadJson) {
-        /*
-         * Even if the invoked operation just returns null, we still need an
-         * unmarshaller to run so we can pull out response metadata.
-         *
-         * We might want to pass this in through the client class so that we
-         * don't have to do this check here.
-         */
-        this.responseUnmarshaller =
-                responseUnmarshaller != null ? responseUnmarshaller : new VoidJsonUnmarshaller<T>();
-
-        this.needsConnectionLeftOpen = needsConnectionLeftOpen;
-        this.isPayloadJson = isPayloadJson;
-
-        this.simpleTypeUnmarshallers = ValidationUtils.assertNotNull(simpleTypeUnmarshallers, "simple type unmarshallers");
-        this.customTypeMarshallers = ValidationUtils.assertNotNull(customTypeMarshallers, "custom type marshallers");
-        this.jsonFactory = ValidationUtils.assertNotNull(jsonFactory, "JSONFactory");
-    }
-
-
-    /**
-     * @see HttpResponseHandler#handle(HttpResponse)
-     */
-    public AmazonWebServiceResponse<T> handle(HttpResponse response) throws Exception {
-        log.trace("Parsing service response JSON");
-
-        String CRC32Checksum = response.getHeaders().get("x-amz-crc32");
-
-        JsonParser jsonParser = null;
-
-        if (shouldParsePayloadAsJson()) {
-            jsonParser = jsonFactory.createParser(response.getContent());
-        }
-
-        try {
-            AmazonWebServiceResponse<T> awsResponse = new AmazonWebServiceResponse<T>();
-            JsonUnmarshallerContext unmarshallerContext = new JsonUnmarshallerContextImpl(
-                    jsonParser, simpleTypeUnmarshallers, customTypeMarshallers, response);
-            registerAdditionalMetadataExpressions(unmarshallerContext);
-
-            T result = responseUnmarshaller.unmarshall(unmarshallerContext);
-
-            // Make sure we read all the data to get an accurate CRC32 calculation.
-            // See https://github.com/aws/aws-sdk-java/issues/1018
-            if (shouldParsePayloadAsJson() && response.getContent() != null) {
-                IOUtils.drainInputStream(response.getContent());
-            }
-
-            if (CRC32Checksum != null) {
-                long serverSideCRC = Long.parseLong(CRC32Checksum);
-                long clientSideCRC = response.getCRC32Checksum();
-                if (clientSideCRC != serverSideCRC) {
-                    throw new CRC32MismatchException(
-                            "Client calculated crc32 checksum didn't match that calculated by server side");
-                }
-            }
-
-            awsResponse.setResult(result);
-
-            Map<String, String> metadata = unmarshallerContext.getMetadata();
-            metadata.put(ResponseMetadata.AWS_REQUEST_ID,
-                         response.getHeaders().get(X_AMZN_REQUEST_ID_HEADER));
-            awsResponse.setResponseMetadata(new ResponseMetadata(metadata));
-
-            log.trace("Done parsing service response");
-            return awsResponse;
-        } finally {
-            if (shouldParsePayloadAsJson()) {
-                try {
-                    jsonParser.close();
-                } catch (IOException e) {
-                    log.warn("Error closing json parser", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Hook for subclasses to override in order to collect additional metadata from service
-     * responses.
-     *
-     * @param unmarshallerContext
-     *            The unmarshaller context used to configure a service's response
-     *            data.
-     */
-    protected void registerAdditionalMetadataExpressions(
-            JsonUnmarshallerContext unmarshallerContext) {
-    }
-
-    public boolean needsConnectionLeftOpen() {
-        return needsConnectionLeftOpen;
-    }
-
-    /**
-     * @return True if the payload will be parsed as JSON, false otherwise.
-     */
-    private boolean shouldParsePayloadAsJson() {
-        return !needsConnectionLeftOpen && isPayloadJson;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/protocol/SdkHttpRequestExecutor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/protocol/SdkHttpRequestExecutor.java
--- ./src/main/java/com/amazonaws/http/protocol/SdkHttpRequestExecutor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/protocol/SdkHttpRequestExecutor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,87 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.protocol;
-
-import java.io.IOException;
-import java.net.Socket;
-
-import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.conn.ManagedHttpClientConnection;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpRequestExecutor;
-
-import com.amazonaws.internal.SdkMetricsSocket;
-import com.amazonaws.internal.SdkSSLMetricsSocket;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.AWSRequestMetrics.Field;
-
-/**
- * Used to capture the http send-request and receive-response latency metrics
- * of the http client library, with no retries involved.
- */
-public class SdkHttpRequestExecutor extends HttpRequestExecutor {
-    @Override
-    protected HttpResponse doSendRequest(
-        final HttpRequest request,
-        final HttpClientConnection conn,
-        final HttpContext context)
-        throws IOException, HttpException {
-        AWSRequestMetrics awsRequestMetrics = (AWSRequestMetrics) context
-            .getAttribute(AWSRequestMetrics.SIMPLE_NAME);
-
-        if (awsRequestMetrics == null) {
-            return super.doSendRequest(request, conn, context);
-        }
-        if (conn instanceof ManagedHttpClientConnection) {
-            ManagedHttpClientConnection managedConn = (ManagedHttpClientConnection)conn;
-            Socket sock = managedConn.getSocket();
-            if (sock instanceof SdkMetricsSocket) {
-                SdkMetricsSocket sdkMetricsSocket = (SdkMetricsSocket)sock;
-                sdkMetricsSocket.setMetrics(awsRequestMetrics);
-            } else if (sock instanceof SdkSSLMetricsSocket) {
-                SdkSSLMetricsSocket sdkSSLMetricsSocket = (SdkSSLMetricsSocket)sock;
-                sdkSSLMetricsSocket.setMetrics(awsRequestMetrics);
-            }
-        }
-        awsRequestMetrics.startEvent(Field.HttpClientSendRequestTime);
-        try {
-            return super.doSendRequest(request, conn, context);
-        } finally {
-            awsRequestMetrics.endEvent(Field.HttpClientSendRequestTime);
-        }
-    }
-
-    @Override
-    protected HttpResponse doReceiveResponse(
-        final HttpRequest          request,
-        final HttpClientConnection conn,
-        final HttpContext          context)
-        throws HttpException, IOException {
-        AWSRequestMetrics awsRequestMetrics = (AWSRequestMetrics) context
-            .getAttribute(AWSRequestMetrics.SIMPLE_NAME);
-        if (awsRequestMetrics == null) {
-            return super.doReceiveResponse(request, conn, context);
-        }
-        awsRequestMetrics.startEvent(Field.HttpClientReceiveResponseTime);
-        try {
-            return super.doReceiveResponse(request, conn, context);
-        } finally {
-            awsRequestMetrics.endEvent(Field.HttpClientReceiveResponseTime);
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/RepeatableInputStreamRequestEntity.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/RepeatableInputStreamRequestEntity.java
--- ./src/main/java/com/amazonaws/http/RepeatableInputStreamRequestEntity.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/RepeatableInputStreamRequestEntity.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,167 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.Request;
-import com.amazonaws.metrics.MetricInputStreamEntity;
-import com.amazonaws.metrics.ServiceMetricType;
-import com.amazonaws.metrics.ThroughputMetricType;
-import com.amazonaws.metrics.internal.ServiceMetricTypeGuesser;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.entity.BasicHttpEntity;
-import org.apache.http.entity.InputStreamEntity;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Custom implementation of {@link RequestEntity} that delegates to an
- * {@link RepeatableInputStreamRequestEntity}, with the one notable difference, that if
- * the underlying InputStream supports being reset, this RequestEntity will
- * report that it is repeatable and will reset the stream on all subsequent
- * attempts to write out the request.
- *
- * TODO : Move this to apache specific package.
- */
-public class RepeatableInputStreamRequestEntity extends BasicHttpEntity {
-
-    /** True if the request entity hasn't been written out yet */
-    private boolean firstAttempt = true;
-
-    /** The underlying InputStreamEntity being delegated to */
-    private InputStreamEntity inputStreamRequestEntity;
-
-    /** The InputStream containing the content to write out */
-    private InputStream content;
-
-    private static final Log log = LogFactory
-            .getLog(RepeatableInputStreamRequestEntity.class);
-
-    /**
-     * Record the original exception if we do attempt a retry, so that if the
-     * retry fails, we can report the original exception. Otherwise, we're most
-     * likely masking the real exception with an error about not being able to
-     * reset far enough back in the input stream.
-     */
-    private IOException originalException;
-
-
-    /**
-     * Creates a new RepeatableInputStreamRequestEntity using the information
-     * from the specified request. If the input stream containing the request's
-     * contents is repeatable, then this RequestEntity will report as being
-     * repeatable.
-     *
-     * @param request
-     *            The details of the request being written out (content type,
-     *            content length, and content).
-     */
-    public RepeatableInputStreamRequestEntity(final Request<?> request) {
-        setChunked(false);
-
-        /*
-         * If we don't specify a content length when we instantiate our
-         * InputStreamRequestEntity, then HttpClient will attempt to
-         * buffer the entire stream contents into memory to determine
-         * the content length.
-         *
-         * TODO: It'd be nice to have easier access to content length and
-         *       content type from the request, instead of having to look
-         *       directly into the headers.
-         */
-        long contentLength = -1;
-        try {
-            String contentLengthString = request.getHeaders().get("Content-Length");
-            if (contentLengthString != null) {
-                contentLength = Long.parseLong(contentLengthString);
-            }
-        } catch (NumberFormatException nfe) {
-            log.warn("Unable to parse content length from request.  " +
-                    "Buffering contents in memory.");
-        }
-
-        String contentType = request.getHeaders().get("Content-Type");
-        ThroughputMetricType type = ServiceMetricTypeGuesser
-                .guessThroughputMetricType(request,
-                        ServiceMetricType.UPLOAD_THROUGHPUT_NAME_SUFFIX,
-                        ServiceMetricType.UPLOAD_BYTE_COUNT_NAME_SUFFIX);
-
-        content = getContent(request);
-        inputStreamRequestEntity = (type == null) ? new InputStreamEntity(content, contentLength) :
-                new MetricInputStreamEntity(type, content, contentLength);
-        inputStreamRequestEntity.setContentType(contentType);
-
-        setContent(content);
-        setContentType(contentType);
-        setContentLength(contentLength);
-    }
-
-    /**
-     * @return The request content input stream or an empty input stream if there is no content.
-     */
-    private InputStream getContent(Request<?> request) {
-        return (request.getContent() == null) ? new ByteArrayInputStream(new byte[0]) :
-                request.getContent();
-    }
-
-    @Override
-    public boolean isChunked() {
-        return false;
-    }
-
-    /**
-     * Returns true if the underlying InputStream supports marking/reseting or
-     * if the underlying InputStreamRequestEntity is repeatable (i.e. its
-     * content length has been set to
-     * {@link InputStreamRequestEntity#CONTENT_LENGTH_AUTO} and therefore its
-     * entire contents will be buffered in memory and can be repeated).
-     *
-     * @see org.apache.commons.httpclient.methods.RequestEntity#isRepeatable()
-     */
-    @Override
-    public boolean isRepeatable() {
-        return content.markSupported() || inputStreamRequestEntity.isRepeatable();
-    }
-
-    /**
-     * Resets the underlying InputStream if this isn't the first attempt to
-     * write out the request, otherwise simply delegates to
-     * InputStreamRequestEntity to write out the data.
-     * <p>
-     * If an error is encountered the first time we try to write the request
-     * entity, we remember the original exception, and report that as the root
-     * cause if we continue to encounter errors, rather than masking the
-     * original error.
-     *
-     * @see org.apache.commons.httpclient.methods.RequestEntity#writeRequest(java.io.OutputStream)
-     */
-    @Override
-    public void writeTo(OutputStream output) throws IOException {
-        try {
-            if (!firstAttempt && isRepeatable()) content.reset();
-
-            firstAttempt = false;
-            inputStreamRequestEntity.writeTo(output);
-        } catch (IOException ioe) {
-            if (originalException == null) originalException = ioe;
-            throw originalException;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/request/HttpRequestFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/request/HttpRequestFactory.java
--- ./src/main/java/com/amazonaws/http/request/HttpRequestFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/request/HttpRequestFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.request;
-
-import com.amazonaws.Request;
-import com.amazonaws.annotation.Beta;
-import com.amazonaws.http.settings.HttpClientSettings;
-
-import java.io.IOException;
-
-/**
- * An interface that can be used to create the http requests that is
- * understood by the http client.
- *
- * @param <T> Request class that is accepted by the underlying http client.
- */
-@Beta
-public interface HttpRequestFactory<T> {
-
-    /**
-     * A factory method for creating http requests accepted by the underlying
-     * http client from the sdk request objects.
-     *
-     * @param request sdk request object.
-     * @param settings configuration to be set for the http request.
-     * @return an instance of request that is accepted by the underlying
-     * http client that SDK uses.
-     */
-    T create(Request<?> request, HttpClientSettings settings) throws IOException;
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/response/AwsResponseHandlerAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/response/AwsResponseHandlerAdapter.java
--- ./src/main/java/com/amazonaws/http/response/AwsResponseHandlerAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/response/AwsResponseHandlerAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,162 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.response;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.AmazonWebServiceResponse;
-import com.amazonaws.AmazonWebServiceResult;
-import com.amazonaws.Request;
-import com.amazonaws.http.AmazonHttpClient;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.http.HttpResponseHandler;
-import com.amazonaws.http.SdkHttpMetadata;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.MetadataCache;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Adapts an {@link HttpResponseHandler < AmazonWebServiceResponse <T>>} to an {@link
- * HttpResponseHandler<T>} (unwrapped result) with proper handling and logging of response
- * metadata.
- *
- * @param <T> Unmarshalled result type
- */
-public class AwsResponseHandlerAdapter<T> implements HttpResponseHandler<T> {
-
-    /**
-     * Logger used for the purpose of logging the AWS request id extracted either from the
-     * httpClientSettings header response or from the response body.
-     */
-    private static final Log requestIdLog = LogFactory.getLog("com.amazonaws.requestId");
-
-    private static final Log requestLog = AmazonHttpClient.requestLog;
-
-    private final HttpResponseHandler<AmazonWebServiceResponse<T>> delegate;
-    private final Request<?> request;
-    private final AWSRequestMetrics awsRequestMetrics;
-    private final MetadataCache responseMetadataCache;
-
-    /**
-     * @param delegate          Response handler to delegate to and unwrap
-     * @param request           Marshalled request
-     * @param awsRequestMetrics Request metrics
-     */
-    public AwsResponseHandlerAdapter(HttpResponseHandler<AmazonWebServiceResponse<T>> delegate,
-                                     Request<?> request,
-                                     AWSRequestMetrics awsRequestMetrics,
-                                     MetadataCache responseMetadataCache) {
-        this.delegate = delegate;
-        this.request = request;
-        this.awsRequestMetrics = awsRequestMetrics;
-        this.responseMetadataCache = responseMetadataCache;
-    }
-
-    @Override
-    public T handle(HttpResponse response) throws Exception {
-        final AmazonWebServiceResponse<T> awsResponse = delegate.handle(response);
-
-        if (awsResponse == null) {
-            throw new RuntimeException("Unable to unmarshall response metadata. Response Code: "
-                                       + response.getStatusCode() + ", Response Text: " +
-                                       response.getStatusText());
-        }
-
-        AmazonWebServiceRequest userRequest = request.getOriginalRequest();
-        if (userRequest.getCloneRoot() != null) {
-            userRequest = userRequest.getCloneRoot();
-        }
-        responseMetadataCache.add(userRequest, awsResponse.getResponseMetadata());
-        final String awsRequestId = awsResponse.getRequestId();
-
-        if (requestLog.isDebugEnabled()) {
-            requestLog
-                    .debug("Received successful response: " + response.getStatusCode() +
-                           ", AWS Request ID: " + awsRequestId);
-        }
-
-        if (!logHeaderRequestId(response)) {
-            // Logs the AWS request ID extracted from the payload if
-            // it is not available from the response header.
-            logResponseRequestId(awsRequestId);
-        }
-        awsRequestMetrics.addProperty(AWSRequestMetrics.Field.AWSRequestID, awsRequestId);
-        return fillInResponseMetadata(awsResponse, response);
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T> T fillInResponseMetadata(AmazonWebServiceResponse<T> awsResponse,
-                                         HttpResponse httpResponse) {
-        final T result = awsResponse.getResult();
-        if (result instanceof AmazonWebServiceResult<?>) {
-            ((AmazonWebServiceResult) result)
-                    .setSdkResponseMetadata(awsResponse.getResponseMetadata())
-                    .setSdkHttpMetadata(SdkHttpMetadata.from(httpResponse));
-        }
-        return result;
-    }
-
-    @Override
-    public boolean needsConnectionLeftOpen() {
-        return delegate.needsConnectionLeftOpen();
-    }
-
-    /**
-     * Used to log the "x-amzn-RequestId" header at DEBUG level, if any, from the response. This
-     * method assumes the apache httpClientSettings request/response has just been successfully
-     * executed. The request id is logged using the "com.amazonaws.requestId" logger if it was
-     * enabled at DEBUG level; otherwise, it is logged at DEBUG level using the
-     * "com.amazonaws.request" logger.
-     *
-     * @return true if the AWS request id is available from the httpClientSettings header; false
-     * otherwise.
-     */
-    private boolean logHeaderRequestId(final HttpResponse response) {
-        final String reqIdHeader = response.getHeaders()
-                .get(HttpResponseHandler.X_AMZN_REQUEST_ID_HEADER);
-        final boolean isHeaderReqIdAvail = reqIdHeader != null;
-
-        if (requestIdLog.isDebugEnabled() || requestLog.isDebugEnabled()) {
-            final String msg = HttpResponseHandler.X_AMZN_REQUEST_ID_HEADER + ": "
-                               + (isHeaderReqIdAvail ? reqIdHeader : "not available");
-            if (requestIdLog.isDebugEnabled()) {
-                requestIdLog.debug(msg);
-            } else {
-                requestLog.debug(msg);
-            }
-        }
-        return isHeaderReqIdAvail;
-    }
-
-    /**
-     * Used to log the request id (extracted from the response) at DEBUG level. This method is
-     * called only if there is no request id present in the httpClientSettings response header. The
-     * request id is logged using the "com.amazonaws.requestId" logger if it was enabled at DEBUG
-     * level; otherwise, it is logged using at DEBUG level using the "com.amazonaws.request"
-     * logger.
-     */
-    private void logResponseRequestId(final String awsRequestId) {
-        if (requestIdLog.isDebugEnabled() || requestLog.isDebugEnabled()) {
-            final String msg = "AWS Request ID: " +
-                               (awsRequestId == null ? "not available" : awsRequestId);
-            if (requestIdLog.isDebugEnabled()) {
-                requestIdLog.debug(msg);
-            } else {
-                requestLog.debug(msg);
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/SdkHttpMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/SdkHttpMetadata.java
--- ./src/main/java/com/amazonaws/http/SdkHttpMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/SdkHttpMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,59 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.annotation.Immutable;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Metadata about the HTTP response.
- */
-@Immutable
-public class SdkHttpMetadata {
-
-    private final Map<String, String> httpHeaders;
-
-    private final int httpStatusCode;
-
-    private SdkHttpMetadata(Map<String, String> httpHeaders, int httpStatusCode) {
-        this.httpHeaders = Collections.unmodifiableMap(httpHeaders);
-        this.httpStatusCode = httpStatusCode;
-    }
-
-    /**
-     * @return All HTTP headers in response.
-     */
-    public Map<String, String> getHttpHeaders() {
-        return httpHeaders;
-    }
-
-    /**
-     * @return HTTP status code of response.
-     */
-    public int getHttpStatusCode() {
-        return httpStatusCode;
-    }
-
-    /**
-     * Static factory to create an {@link SdkHttpMetadata} from the details in a {@link
-     * HttpResponse}.
-     */
-    public static SdkHttpMetadata from(HttpResponse httpResponse) {
-        return new SdkHttpMetadata(httpResponse.getHeaders(), httpResponse.getStatusCode());
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/settings/HttpClientSettings.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/settings/HttpClientSettings.java
--- ./src/main/java/com/amazonaws/http/settings/HttpClientSettings.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/settings/HttpClientSettings.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,179 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.settings;
-
-import com.amazonaws.ProxyAuthenticationMethod;
-import java.net.InetAddress;
-import java.security.SecureRandom;
-
-import com.amazonaws.ApacheHttpClientConfig;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.DnsResolver;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.ValidationUtils;
-import java.util.List;
-
-/**
- * A convienient class that expose all settings in {@link ClientConfiguration} and other internal settings to the
- * underlying http client.
- */
-@SdkInternalApi
-public class HttpClientSettings {
-
-    private final ClientConfiguration config;
-
-    private final boolean useBrowserCompatibleHostNameVerifier;
-
-    private final boolean calculateCRC32FromCompressedData;
-
-    HttpClientSettings(final ClientConfiguration config,
-                       final boolean useBrowserCompatibleHostNameVerifier,
-                       final boolean calculateCRC32FromCompressedData) {
-        this.config = ValidationUtils.assertNotNull(config, "client configuration");
-        this.useBrowserCompatibleHostNameVerifier = useBrowserCompatibleHostNameVerifier;
-        this.calculateCRC32FromCompressedData = calculateCRC32FromCompressedData;
-    }
-
-    public static HttpClientSettings adapt(final ClientConfiguration config,
-            final boolean useBrowserCompatibleHostNameVerifier,
-            final boolean calculateCRC32FromCompressedData) {
-        return new HttpClientSettings(config, useBrowserCompatibleHostNameVerifier, calculateCRC32FromCompressedData);
-    }
-
-    public static HttpClientSettings adapt(final ClientConfiguration config,
-                                           final boolean useBrowserCompatibleHostNameVerifier) {
-        return adapt(config, useBrowserCompatibleHostNameVerifier, false);
-    }
-
-    public static HttpClientSettings adapt(final ClientConfiguration config) {
-        return adapt(config, false);
-    }
-
-    public boolean useBrowserCompatibleHostNameVerifier() {
-        return useBrowserCompatibleHostNameVerifier;
-    }
-
-    public boolean calculateCRC32FromCompressedData() {
-        return calculateCRC32FromCompressedData;
-    }
-
-    public int getMaxConnections() {
-        return config.getMaxConnections();
-    }
-
-    public InetAddress getLocalAddress() {
-        return config.getLocalAddress();
-    }
-
-    public String getProxyHost() {
-        return config.getProxyHost();
-    }
-
-    public int getProxyPort() {
-        return config.getProxyPort();
-    }
-
-    public String getProxyUsername() {
-        return config.getProxyUsername();
-    }
-
-    public String getProxyPassword() {
-        return config.getProxyPassword();
-    }
-
-    public String getNonProxyHosts() {
-        return config.getNonProxyHosts();
-    }
-
-    public List<ProxyAuthenticationMethod> getProxyAuthenticationMethods() {
-        return config.getProxyAuthenticationMethods();
-    }
-
-    public boolean useReaper() {
-        return config.useReaper();
-    }
-
-    public boolean useGzip() {
-        return config.useGzip();
-    }
-
-    public DnsResolver getDnsResolver() {
-        return config.getDnsResolver();
-    }
-
-    public ApacheHttpClientConfig getApacheHttpClientConfig() {
-        return config.getApacheHttpClientConfig();
-    }
-
-    public int getSocketTimeout() {
-        return config.getSocketTimeout();
-    }
-
-    public int[] getSocketBufferSize() {
-        return config.getSocketBufferSizeHints();
-    }
-
-    public boolean useTcpKeepAlive() {
-        return config.useTcpKeepAlive();
-    }
-
-    public SecureRandom getSecureRandom() {
-        return config.getSecureRandom();
-    }
-
-    public int getConnectionTimeout() {
-        return config.getConnectionTimeout();
-    }
-
-    public int getConnectionPoolRequestTimeout() {
-        return config.getConnectionTimeout();
-    }
-
-    public long getConnectionPoolTTL() {
-        return config.getConnectionTTL();
-    }
-
-    public long getMaxIdleConnectionTime() {
-        return config.getConnectionMaxIdleMillis();
-    }
-
-    public int getValidateAfterInactivityMillis() {
-        return config.getValidateAfterInactivityMillis();
-    }
-
-    public String getProxyWorkstation() {
-        return config.getProxyWorkstation();
-    }
-
-    public String getProxyDomain() {
-        return config.getProxyDomain();
-    }
-
-    public boolean isPreemptiveBasicProxyAuth() {
-        return config.isPreemptiveBasicProxyAuth();
-    }
-
-    public boolean isUseExpectContinue() {
-        return config.isUseExpectContinue();
-    }
-
-    public boolean isProxyEnabled() {
-        return getProxyHost() != null && getProxyPort() > 0;
-    }
-
-    public boolean isAuthenticatedProxy() {
-        return getProxyUsername() != null && getProxyPassword() != null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/StaxResponseHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/StaxResponseHandler.java
--- ./src/main/java/com/amazonaws/http/StaxResponseHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/StaxResponseHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,166 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-import com.amazonaws.AmazonWebServiceResponse;
-import com.amazonaws.ResponseMetadata;
-import com.amazonaws.transform.StaxUnmarshallerContext;
-import com.amazonaws.transform.Unmarshaller;
-import com.amazonaws.transform.VoidStaxUnmarshaller;
-import com.amazonaws.util.StringUtils;
-import com.amazonaws.util.XmlUtils;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLStreamException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Default implementation of HttpResponseHandler that handles a successful
- * response from an AWS service and unmarshalls the result using a StAX
- * unmarshaller.
- *
- * @param <T> Indicates the type being unmarshalled by this response handler.
- */
-public class StaxResponseHandler<T> implements HttpResponseHandler<AmazonWebServiceResponse<T>> {
-
-    /**
-     * The StAX unmarshaller to use when handling the response
-     */
-    private Unmarshaller<T, StaxUnmarshallerContext> responseUnmarshaller;
-
-    /**
-     * Shared logger for profiling information
-     */
-    private static final Log log = LogFactory.getLog("com.amazonaws.request");
-
-    /**
-     * Constructs a new response handler that will use the specified StAX
-     * unmarshaller to unmarshall the service response and uses the specified
-     * response element path to find the root of the business data in the
-     * service's response.
-     *
-     * @param responseUnmarshaller The StAX unmarshaller to use on the response.
-     */
-    public StaxResponseHandler(Unmarshaller<T, StaxUnmarshallerContext> responseUnmarshaller) {
-        this.responseUnmarshaller = responseUnmarshaller;
-
-        /*
-         * Even if the invoked operation just returns null, we still need an
-         * unmarshaller to run so we can pull out response metadata.
-         *
-         * We might want to pass this in through the client class so that we
-         * don't have to do this check here.
-         */
-        if (this.responseUnmarshaller == null) {
-            this.responseUnmarshaller = new VoidStaxUnmarshaller<T>();
-        }
-    }
-
-
-    /**
-     * @see HttpResponseHandler#handle(HttpResponse)
-     */
-    public AmazonWebServiceResponse<T> handle(HttpResponse response) throws Exception {
-        log.trace("Parsing service response XML");
-        InputStream content = response.getContent();
-        if (content == null) {
-            content = new ByteArrayInputStream("<eof/>".getBytes(StringUtils.UTF8));
-        }
-
-        XMLEventReader eventReader;
-        try {
-            eventReader = XmlUtils.getXmlInputFactory().createXMLEventReader(content);
-        } catch (XMLStreamException e) {
-            throw handleXmlStreamException(e);
-        }
-
-        try {
-            AmazonWebServiceResponse<T> awsResponse = new AmazonWebServiceResponse<T>();
-            StaxUnmarshallerContext unmarshallerContext = new StaxUnmarshallerContext(eventReader, response.getHeaders());
-            unmarshallerContext.registerMetadataExpression("ResponseMetadata/RequestId", 2, ResponseMetadata.AWS_REQUEST_ID);
-            unmarshallerContext.registerMetadataExpression("requestId", 2, ResponseMetadata.AWS_REQUEST_ID);
-            registerAdditionalMetadataExpressions(unmarshallerContext);
-
-            T result = responseUnmarshaller.unmarshall(unmarshallerContext);
-            awsResponse.setResult(result);
-
-            Map<String, String> metadata = unmarshallerContext.getMetadata();
-            Map<String, String> responseHeaders = response.getHeaders();
-            if (responseHeaders != null) {
-                if (responseHeaders.get(X_AMZN_REQUEST_ID_HEADER) != null) {
-                    metadata.put(ResponseMetadata.AWS_REQUEST_ID,
-                                 responseHeaders.get(X_AMZN_REQUEST_ID_HEADER));
-                }
-            }
-            awsResponse.setResponseMetadata(getResponseMetadata(metadata));
-
-            log.trace("Done parsing service response");
-            return awsResponse;
-        } catch (XMLStreamException e) {
-            throw handleXmlStreamException(e);
-        } finally {
-            try {
-                eventReader.close();
-            } catch (XMLStreamException e) {
-                log.warn("Error closing xml parser", e);
-            }
-        }
-    }
-
-    /**
-     * If the exception was caused by an {@link IOException}, wrap it an another IOE so
-     * that it will be exposed to the RetryPolicy.
-     */
-    private Exception handleXmlStreamException(XMLStreamException e) throws Exception {
-        if (e.getNestedException() instanceof IOException) {
-            return new IOException(e);
-        }
-        return e;
-    }
-
-    /**
-     * Create the default {@link ResponseMetadata}. Subclasses may override this to create a
-     * subclass of {@link ResponseMetadata}. Currently only SimpleDB does this.
-     */
-    protected ResponseMetadata getResponseMetadata(Map<String, String> metadata) {
-        return new ResponseMetadata(metadata);
-    }
-
-    /**
-     * Hook for subclasses to override in order to collect additional metadata
-     * from service responses.
-     *
-     * @param unmarshallerContext The unmarshaller context used to configure a service's response
-     *                            data.
-     */
-    protected void registerAdditionalMetadataExpressions(StaxUnmarshallerContext unmarshallerContext) {
-    }
-
-    /**
-     * Since this response handler completely consumes all the data from the
-     * underlying HTTP connection during the handle method, we don't need to
-     * keep the HTTP connection open.
-     *
-     * @see com.amazonaws.http.HttpResponseHandler#needsConnectionLeftOpen()
-     */
-    public boolean needsConnectionLeftOpen() {
-        return false;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTaskImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTaskImpl.java
--- ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTaskImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTaskImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Implementation of {@link ClientExecutionAbortTask} that interrupts the caller thread and aborts
- * any HTTP request when triggered
- */
-@SdkInternalApi
-public class ClientExecutionAbortTaskImpl implements ClientExecutionAbortTask {
-
-    private volatile boolean hasTaskExecuted;
-    private HttpRequestBase currentHttpRequest;
-    private final Thread thread;
-
-    public ClientExecutionAbortTaskImpl(Thread thread) {
-        this.thread = thread;
-    }
-
-    @Override
-    public void run() {
-        hasTaskExecuted = true;
-        if (!thread.isInterrupted()) {
-            thread.interrupt();
-        }
-        if (!currentHttpRequest.isAborted()) {
-            currentHttpRequest.abort();
-        }
-    }
-
-    public void setCurrentHttpRequest(HttpRequestBase newRequest) {
-        this.currentHttpRequest = newRequest;
-    }
-
-    public boolean hasClientExecutionAborted() {
-        return hasTaskExecuted;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTask.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTask.java
--- ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTask.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTask.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,44 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Task to be scheduled by {@link ClientExecutionTimer}
- */
-@SdkInternalApi
-public interface ClientExecutionAbortTask extends Runnable {
-
-    /**
-     * Client Execution timer task needs to abort the current running HTTP request when executed.
-     * 
-     * @param newRequest
-     */
-    public void setCurrentHttpRequest(HttpRequestBase newRequest);
-
-    /**
-     * @return True if client execution has been aborted by the timer task. False otherwise
-     */
-    public boolean hasClientExecutionAborted();
-
-    /**
-     * @return True if the timer task has been scheduled. False if client execution timeout is
-     *         disabled for this request
-     */
-    public boolean isEnabled();
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTaskImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTaskImpl.java
--- ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTaskImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTaskImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,59 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import java.util.concurrent.ScheduledFuture;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.ValidationUtils;
-
-/**
- * Keeps track of the scheduled {@link ClientExecutionAbortTask} and the associated {@link Future}
- */
-@SdkInternalApi
-public class ClientExecutionAbortTrackerTaskImpl implements ClientExecutionAbortTrackerTask {
-
-    private final ClientExecutionAbortTask task;
-    private final ScheduledFuture<?> future;
-
-    public ClientExecutionAbortTrackerTaskImpl(final ClientExecutionAbortTask task, final ScheduledFuture<?> future) {
-        this.task = ValidationUtils.assertNotNull(task, "task");
-        this.future = ValidationUtils.assertNotNull(future, "future");
-    }
-
-    @Override
-    public void setCurrentHttpRequest(HttpRequestBase newRequest) {
-        task.setCurrentHttpRequest(newRequest);
-    }
-
-    @Override
-    public boolean hasTimeoutExpired() {
-        return task.hasClientExecutionAborted();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return task.isEnabled();
-    }
-
-    @Override
-    public void cancelTask() {
-        // Ensure task is canceled even if it's running as we don't want the Thread to be
-        // interrupted in the caller's code
-        future.cancel(false);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTask.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTask.java
--- ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTask.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionAbortTrackerTask.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,44 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-@SdkInternalApi
-public interface ClientExecutionAbortTrackerTask {
-
-    /**
-     * Client execution timer task needs to abort the current running HTTP request when executed.
-     * 
-     * @param newRequest
-     */
-    void setCurrentHttpRequest(HttpRequestBase newRequest);
-
-    /**
-     * @return True if client execution has been aborted by the timer task. False otherwise
-     */
-    boolean hasTimeoutExpired();
-
-    /**
-     * @return True if the timer task has been scheduled. False if the client execution timeout is
-     *         disabled for this request
-     */
-    boolean isEnabled();
-
-    void cancelTask();
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimeoutException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimeoutException.java
--- ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimeoutException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimeoutException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import com.amazonaws.SdkClientException;
-
-public class ClientExecutionTimeoutException extends SdkClientException {
-
-    public ClientExecutionTimeoutException() {
-        this("Client execution did not complete before the specified timeout configuration.");
-    }
-
-    public ClientExecutionTimeoutException(String message) {
-        super(message);
-    }
-
-    private static final long serialVersionUID = 4861767589924758934L;
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimer.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimer.java
--- ./src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimer.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/ClientExecutionTimer.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,102 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.http.AmazonHttpClient;
-import com.amazonaws.http.timers.TimeoutThreadPoolBuilder;
-
-/**
- * Represents a timer to enforce a timeout on the total client execution time. That is the time
- * spent executing request handlers, any HTTP request including retries, unmarshalling, etc.
- * Essentially all the time spent in {@link AmazonHttpClient}
- */
-// DO NOT override finalize(). The shutdown() method is called from AmazonHttpClient#shutdown()
-// which is called from it's finalize() method.  Since finalize methods can be be called in any
-// order and even concurrently, we need to rely on AmazonHttpClient to call our shutdown() method.
-@SdkInternalApi
-@ThreadSafe
-public class ClientExecutionTimer {
-
-    private static final String threadNamePrefix = "AwsSdkClientExecutionTimerThread";
-
-    private volatile ScheduledThreadPoolExecutor executor;
-
-    /**
-     * Start the timer with the specified timeout and return a object that can be used to track the
-     * state of the timer and cancel it if need be.
-     * 
-     * @param clientExecutionTimeoutMillis
-     *            A positive value here enables the timer, a non-positive value disables it and
-     *            returns a dummy tracker task
-     * @return Implementation of {@link ClientExecutionAbortTrackerTaskImpl} to query the state of
-     *         the task, provide it with up to date context, and cancel it if appropriate
-     */
-    public ClientExecutionAbortTrackerTask startTimer(int clientExecutionTimeoutMillis) {
-        if (isTimeoutDisabled(clientExecutionTimeoutMillis)) {
-            return NoOpClientExecutionAbortTrackerTask.INSTANCE;
-        } else if (executor == null) {
-            initializeExecutor();
-        }
-        return scheduleTimerTask(clientExecutionTimeoutMillis);
-    }
-
-    /**
-     * Executor is lazily initialized as it's not compatible with Java 6
-     */
-    private synchronized void initializeExecutor() {
-        if (executor == null) {
-            executor = TimeoutThreadPoolBuilder.buildDefaultTimeoutThreadPool(threadNamePrefix);
-        }
-    }
-
-    /**
-     * This method is current exposed for testing purposes
-     * 
-     * @return The underlying {@link ScheduledThreadPoolExecutor}
-     */
-    @SdkTestInternalApi
-    public ScheduledThreadPoolExecutor getExecutor() {
-        return this.executor;
-    }
-
-    /**
-     * Shutdown the underlying {@link ScheduledThreadPoolExecutor}. Should be invoked when
-     * {@link AmazonHttpClient} is shutdown
-     */
-    public synchronized void shutdown() {
-        if (executor != null) {
-            executor.shutdown();
-        }
-    }
-
-    private ClientExecutionAbortTrackerTask scheduleTimerTask(int clientExecutionTimeoutMillis) {
-        ClientExecutionAbortTask timerTask = new ClientExecutionAbortTaskImpl(Thread.currentThread());
-        ScheduledFuture<?> timerTaskFuture = executor.schedule(timerTask, clientExecutionTimeoutMillis,
-                TimeUnit.MILLISECONDS);
-        return new ClientExecutionAbortTrackerTaskImpl(timerTask, timerTaskFuture);
-    }
-
-    private boolean isTimeoutDisabled(int clientExecutionTimeoutMillis) {
-        return clientExecutionTimeoutMillis <= 0;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/NoOpClientExecutionAbortTrackerTask.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/NoOpClientExecutionAbortTrackerTask.java
--- ./src/main/java/com/amazonaws/http/timers/client/NoOpClientExecutionAbortTrackerTask.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/NoOpClientExecutionAbortTrackerTask.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-/**
- * Dummy implementation of {@link ClientExecutionAbortTrackerTask} used when the timer is disabled
- * for a request
- */
-public class NoOpClientExecutionAbortTrackerTask implements ClientExecutionAbortTrackerTask {
-
-    public static final NoOpClientExecutionAbortTrackerTask INSTANCE = new NoOpClientExecutionAbortTrackerTask();
-
-    // Singleton
-    private NoOpClientExecutionAbortTrackerTask() {
-    }
-
-    @Override
-    public void setCurrentHttpRequest(HttpRequestBase newRequest) {
-    }
-
-    @Override
-    public boolean hasTimeoutExpired() {
-        return false;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return false;
-    }
-
-    @Override
-    public void cancelTask() {
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/client/SdkInterruptedException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/SdkInterruptedException.java
--- ./src/main/java/com/amazonaws/http/timers/client/SdkInterruptedException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/client/SdkInterruptedException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.client;
-
-import com.amazonaws.Response;
-
-public class SdkInterruptedException extends InterruptedException {
-
-    private static final long serialVersionUID = 8194951388566545094L;
-
-    private final transient Response<?> response;
-
-    public SdkInterruptedException(Response<?> response) {
-        this.response = response;
-    }
-
-    public Response<?> getResponse() {
-        return response;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/package-info.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/package-info.java
--- ./src/main/java/com/amazonaws/http/timers/package-info.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/package-info.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-/**
- * Classes for the request timeout and client execution timeout features. See
- * {@link com.amazonaws.ClientConfiguration} and {@link com.amazonaws.AmazonWebServiceRequest} for
- * more information on enabling these features. All classes within this package are internal and
- * should not be used outside the SDK.
- */
-@com.amazonaws.annotation.SdkInternalApi
-package com.amazonaws.http.timers;
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskImpl.java
--- ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.request;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Implementation of {@link HttpRequestAbortTask} that aborts the tracking {@link HttpRequestBase}
- * when triggered
- */
-@SdkInternalApi
-public class HttpRequestAbortTaskImpl implements HttpRequestAbortTask {
-
-    private final HttpRequestBase httpRequest;
-    private volatile boolean httpRequestAborted;
-
-    public HttpRequestAbortTaskImpl(final HttpRequestBase httpRequest) {
-        this.httpRequest = httpRequest;
-    }
-
-    @Override
-    public void run() {
-        if (!httpRequest.isAborted()) {
-            httpRequestAborted = true;
-            httpRequest.abort();
-        }
-    }
-
-    public boolean httpRequestAborted() {
-        return httpRequestAborted;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTask.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTask.java
--- ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTask.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTask.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.request;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Task to be scheduled by {@link HttpRequestTimer}
- */
-@SdkInternalApi
-public interface HttpRequestAbortTask extends Runnable {
-
-    public boolean httpRequestAborted();
-
-    public boolean isEnabled();
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTrackerImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTrackerImpl.java
--- ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTrackerImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTrackerImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.request;
-
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledFuture;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.ValidationUtils;
-
-/**
- * Keeps track of the scheduled {@link HttpRequestAbortTask} and the associated {@link Future}
- */
-@SdkInternalApi
-public class HttpRequestAbortTaskTrackerImpl implements HttpRequestAbortTaskTracker {
-
-    private final HttpRequestAbortTask task;
-    private final ScheduledFuture<?> future;
-
-    public HttpRequestAbortTaskTrackerImpl(final HttpRequestAbortTask task, final ScheduledFuture<?> future) {
-        this.task = ValidationUtils.assertNotNull(task, "task");
-        this.future = ValidationUtils.assertNotNull(future, "future");
-    }
-
-    @Override
-    public boolean httpRequestAborted() {
-        return task.httpRequestAborted();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return task.isEnabled();
-    }
-
-    @Override
-    public void cancelTask() {
-        future.cancel(false);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTracker.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTracker.java
--- ./src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTracker.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestAbortTaskTracker.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.request;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Returned by {@link HttpRequestTimer} to track a scheduled timer task.
- */
-@SdkInternalApi
-public interface HttpRequestAbortTaskTracker {
-
-    /**
-     * @return True if the HTTP request the scheduled task is tracking has been aborted by the task.
-     *         False otherwise
-     */
-    boolean httpRequestAborted();
-
-    /**
-     * @return True if the timer is enabled for this request. False otherwise
-     */
-    boolean isEnabled();
-
-    /**
-     * Cancel the timer task. This should be called when the request completes within the timeout
-     * otherwise the task will wake up and abort the HTTP request
-     */
-    void cancelTask();
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/request/HttpRequestTimer.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestTimer.java
--- ./src/main/java/com/amazonaws/http/timers/request/HttpRequestTimer.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/HttpRequestTimer.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.request;
-
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.http.timers.TimeoutThreadPoolBuilder;
-
-/**
- * Represents a timer class to enforce HTTP request timeouts.
- */
-// DO NOT override finalize(). The shutdown() method is called from AmazonHttpClient#shutdown()
-// which is called from it's finalize() method. Since finalize methods can be be called in any order
-// and even concurrently, we need to rely on AmazonHttpClient to call our shutdown() method.
-@ThreadSafe
-@SdkInternalApi
-public class HttpRequestTimer {
-
-    private static final String threadNamePrefix = "AwsSdkRequestTimerThread";
-
-    private volatile ScheduledThreadPoolExecutor executor;
-
-    /**
-     * Start the timer with the specified timeout and return a object that can be used to track the
-     * state of the timer and cancel it if need be.
-     *
-     * @param apacheRequest
-     *            HTTP request this timer will abort if triggered.
-     * @param requestTimeoutMillis
-     *            A positive value here enables the timer, a non-positive value disables it and
-     *            returns a dummy tracker task
-     * @return Implementation of {@link HttpRequestAbortTaskTrackerImpl} to query the state of the
-     *         task and cancel it if appropriate
-     */
-    public HttpRequestAbortTaskTracker startTimer(final HttpRequestBase apacheRequest, final int requestTimeoutMillis) {
-        if (isTimeoutDisabled(requestTimeoutMillis)) {
-            return NoOpHttpRequestAbortTaskTracker.INSTANCE;
-        } else if (executor == null) {
-            initializeExecutor();
-        }
-        HttpRequestAbortTaskImpl timerTask = new HttpRequestAbortTaskImpl(apacheRequest);
-        ScheduledFuture<?> timerTaskFuture = executor.schedule(timerTask, requestTimeoutMillis, TimeUnit.MILLISECONDS);
-        return new HttpRequestAbortTaskTrackerImpl(timerTask, timerTaskFuture);
-    }
-
-    private boolean isTimeoutDisabled(final int requestTimeoutMillis) {
-        return requestTimeoutMillis <= 0;
-    }
-
-    /**
-     * Executor is lazily initialized as it's not compatible with Java 6
-     */
-    private synchronized void initializeExecutor() {
-        if (executor == null) {
-            executor = TimeoutThreadPoolBuilder.buildDefaultTimeoutThreadPool(threadNamePrefix);
-        }
-    }
-
-    /**
-     * Shutdown the underlying {@link ScheduledThreadPoolExecutor}. Should be invoked when
-     * {@link com.amazonaws.http.AmazonHttpClient} is shutdown
-     */
-    public synchronized void shutdown() {
-        if (executor != null) {
-            executor.shutdown();
-        }
-    }
-
-    /**
-     * This method is current exposed for testing purposes
-     * 
-     * @return The underlying {@link ScheduledThreadPoolExecutor}
-     */
-    @SdkTestInternalApi
-    public ScheduledThreadPoolExecutor getExecutor() {
-        return executor;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/request/NoOpHttpRequestAbortTaskTracker.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/NoOpHttpRequestAbortTaskTracker.java
--- ./src/main/java/com/amazonaws/http/timers/request/NoOpHttpRequestAbortTaskTracker.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/request/NoOpHttpRequestAbortTaskTracker.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers.request;
-
-/**
- * Dummy implementation of {@link HttpRequestAbortTaskTracker} used when the timer is disabled for a
- * request
- */
-public class NoOpHttpRequestAbortTaskTracker implements HttpRequestAbortTaskTracker {
-
-    public static final NoOpHttpRequestAbortTaskTracker INSTANCE = new NoOpHttpRequestAbortTaskTracker();
-
-    // Singleton
-    private NoOpHttpRequestAbortTaskTracker() {
-    }
-
-    @Override
-    public boolean httpRequestAborted() {
-        return false;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return false;
-    }
-
-    @Override
-    public void cancelTask() {
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/timers/TimeoutThreadPoolBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/TimeoutThreadPoolBuilder.java
--- ./src/main/java/com/amazonaws/http/timers/TimeoutThreadPoolBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/timers/TimeoutThreadPoolBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,93 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http.timers;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Utility class to build the {@link ScheduledThreadPoolExecutor} for the request timeout and client
- * execution timeout features
- */
-@SdkInternalApi
-public class TimeoutThreadPoolBuilder {
-    
-    /**
-     * Creates a {@link ScheduledThreadPoolExecutor} with custom name for the threads.
-     *
-     * @param name the prefix to add to the thread name in ThreadFactory.
-     * @return The default thread pool for request timeout and client execution timeout features.
-     */
-    public static ScheduledThreadPoolExecutor buildDefaultTimeoutThreadPool(final String name) {
-        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5, getThreadFactory(name));
-        safeSetRemoveOnCancel(executor);
-        executor.setKeepAliveTime(5, TimeUnit.SECONDS);
-        executor.allowCoreThreadTimeOut(true);
-
-        return executor;
-    }
-
-    private static ThreadFactory getThreadFactory(final String name) {
-        return new ThreadFactory() {
-            private int threadCount = 1;
-
-            public Thread newThread(Runnable r) {
-                Thread thread = new Thread(r);
-                if (name != null) {
-                    thread.setName(name + "-" + threadCount++);
-                }
-                thread.setPriority(Thread.MAX_PRIORITY);
-                return thread;
-            }
-        };
-    }
-
-    /**
-     * {@link ScheduledThreadPoolExecutor#setRemoveOnCancelPolicy(boolean)} is not available in Java
-     * 6 so we invoke it with reflection to be able to compile against Java 6.
-     * 
-     * @param executor
-     */
-    private static void safeSetRemoveOnCancel(ScheduledThreadPoolExecutor executor) {
-        try {
-            executor.getClass().getMethod("setRemoveOnCancelPolicy", boolean.class).invoke(executor, Boolean.TRUE);
-        } catch (IllegalAccessException e) {
-            throwSetRemoveOnCancelException(e);
-        } catch (IllegalArgumentException e) {
-            throwSetRemoveOnCancelException(e);
-        } catch (InvocationTargetException e) {
-            throwSetRemoveOnCancelException(e.getCause());
-        } catch (NoSuchMethodException e) {
-            throw new SdkClientException("The request timeout feature is only available for Java 1.7 and above.");
-        } catch (SecurityException e) {
-            throw new SdkClientException("The request timeout feature needs additional permissions to function.", e);
-        }
-    }
-
-    /**
-     * Wrap exception caused by calling setRemoveOnCancel in a {@link SdkClientException}.
-     * 
-     * @param cause
-     *            Root cause of exception
-     */
-    private static void throwSetRemoveOnCancelException(Throwable cause) {
-        throw new SdkClientException("Unable to setRemoveOnCancelPolicy for request timeout thread pool", cause);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/http/UnreliableTestConfig.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/UnreliableTestConfig.java
--- ./src/main/java/com/amazonaws/http/UnreliableTestConfig.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/http/UnreliableTestConfig.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,71 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.http;
-
-/**
- * Used to configure the conditions for injecting content input stream failures
- * for testing purposes.
- */
-class UnreliableTestConfig {
-    private int maxNumErrors = 1;
-    private int bytesReadBeforeException = 100;
-    private boolean isFakeIOException;
-    private int resetIntervalBeforeException = 2;
-
-    int getMaxNumErrors() {
-        return maxNumErrors;
-    }
-
-    int getBytesReadBeforeException() {
-        return bytesReadBeforeException;
-    }
-
-    boolean isFakeIOException() {
-        return isFakeIOException;
-    }
-
-    int getResetIntervalBeforeException() {
-        return resetIntervalBeforeException;
-    }
-
-    UnreliableTestConfig withMaxNumErrors(int maxNumErrors) {
-        this.maxNumErrors = maxNumErrors;
-        return this;
-    }
-
-    UnreliableTestConfig withBytesReadBeforeException(
-            int bytesReadBeforeException) {
-        this.bytesReadBeforeException = bytesReadBeforeException;
-        return this;
-    }
-
-    UnreliableTestConfig withFakeIOException(boolean isFakeIOException) {
-        this.isFakeIOException = isFakeIOException;
-        return this;
-    }
-
-    /**
-     * Used to control whether an exception would be thrown based on the reset
-     * recurrence; not applicable if set to zero. For example, if
-     * resetIntervalBeforeException == n, the exception can only be thrown
-     * before the n_th reset (or after the n_th minus 1 reset), 2n_th reset (or
-     * after the 2n_th minus 1) reset), etc.
-     */
-    UnreliableTestConfig withResetIntervalBeforeException(
-            int resetIntervalBeforeException) {
-        this.resetIntervalBeforeException = resetIntervalBeforeException;
-        return this;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/HttpMethod.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/HttpMethod.java
--- ./src/main/java/com/amazonaws/HttpMethod.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/HttpMethod.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,24 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-/**
- * Enumeration of valid HTTP methods.
- */
-public enum HttpMethod {
-
-    GET, POST, PUT, DELETE, HEAD, PATCH;
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/ImmutableRequest.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ImmutableRequest.java
--- ./src/main/java/com/amazonaws/ImmutableRequest.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ImmutableRequest.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,114 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *   http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws;
-
-import com.amazonaws.http.HttpMethodName;
-
-import java.io.InputStream;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Represents a request being sent to an Amazon Web Service, including the
- * parameters being sent as part of the request, the endpoint to which the
- * request should be sent, etc.
- * Members of this class should be considered read-only and not mutated
- *
- * @param <T> The type of original, user facing request represented by this
- *            request.
- */
-public interface ImmutableRequest<T> {
-    /**
-     * Returns a map of all the headers included in this request.
-     *
-     * @return A map of all the headers included in this request.
-     */
-    Map<String, String> getHeaders();
-
-    /**
-     * Returns the path to the resource being requested.
-     *
-     * @return The path to the resource being requested.
-     */
-    String getResourcePath();
-
-    /**
-     * Returns a map of all parameters in this request.
-     *
-     * @return A map of all parameters in this request.
-     */
-    Map<String, List<String>> getParameters();
-
-    /**
-     * Returns the service endpoint (ex: "https://ec2.amazonaws.com") to which
-     * this request should be sent.
-     *
-     * @return The service endpoint to which this request should be sent.
-     */
-    URI getEndpoint();
-
-    /**
-     * Returns the HTTP method (GET, POST, etc) to use when sending this
-     * request.
-     *
-     * @return The HTTP method to use when sending this request.
-     */
-    HttpMethodName getHttpMethod();
-
-    /**
-     * Returns the optional value for time offset for this request.  This
-     * will be used by the signer to adjust for potential clock skew.
-     * Value is in seconds, positive values imply the current clock is "fast",
-     * negative values imply clock is slow.
-     *
-     * @return The optional value for time offset (in seconds) for this request.
-     */
-    int getTimeOffset();
-
-    /**
-     * Returns the optional stream containing the payload data to include for
-     * this request. Not all requests will contain payload data.
-     *
-     * @return The optional stream containing the payload data to include for
-     *         this request.
-     */
-    InputStream getContent();
-
-    /**
-     * Returns the optional raw stream containing the payload data to include
-     * for this request, with all progress stream wrappers. Not all requests
-     * contain payload data.
-     *
-     * @return The optional raw stream containing the payload data to include
-     *         for this request, with all progress stream wrappers removed.
-     */
-    InputStream getContentUnwrapped();
-
-    /**
-     * Returns the read limit info about the original request.
-     */
-    ReadLimitInfo getReadLimitInfo();
-
-    /**
-     * Returns the original, user facing request object which this internal
-     * request object is representing.
-     *
-     * @return an instance of request as an <code>Object</code>.
-     */
-    Object getOriginalRequestObject();
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/AmazonWebServiceRequestAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/AmazonWebServiceRequestAdapter.java
--- ./src/main/java/com/amazonaws/internal/AmazonWebServiceRequestAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/AmazonWebServiceRequestAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,92 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.RequestClientOptions;
-import com.amazonaws.RequestConfig;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.event.ProgressListener;
-import com.amazonaws.metrics.RequestMetricCollector;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Adapts the configuration present in {@link AmazonWebServiceRequest} to {@link RequestConfig}.
- */
-@SdkInternalApi
-public final class AmazonWebServiceRequestAdapter extends RequestConfig {
-
-    private final AmazonWebServiceRequest request;
-
-    public AmazonWebServiceRequestAdapter(AmazonWebServiceRequest request) {
-        this.request = request;
-    }
-
-    @Override
-    public ProgressListener getProgressListener() {
-        return request.getGeneralProgressListener();
-    }
-
-    @Override
-    public RequestMetricCollector getRequestMetricsCollector() {
-        return request.getRequestMetricCollector();
-    }
-
-    @Override
-    public AWSCredentialsProvider getCredentialsProvider() {
-        return request.getRequestCredentialsProvider();
-    }
-
-    @Override
-    public Map<String, String> getCustomRequestHeaders() {
-        return (request.getCustomRequestHeaders() == null) ? Collections.<String, String>emptyMap() :
-                request.getCustomRequestHeaders();
-    }
-
-    @Override
-    public Map<String, List<String>> getCustomQueryParameters() {
-        return (request.getCustomQueryParameters() == null) ? Collections.<String, List<String>>emptyMap() :
-                request.getCustomQueryParameters();
-    }
-
-    @Override
-    public Integer getRequestTimeout() {
-        return request.getSdkRequestTimeout();
-    }
-
-    @Override
-    public Integer getClientExecutionTimeout() {
-        return request.getSdkClientExecutionTimeout();
-    }
-
-    @Override
-    public RequestClientOptions getRequestClientOptions() {
-        return request.getRequestClientOptions();
-    }
-
-    @Override
-    public String getRequestType() {
-        return request.getClass().getSimpleName();
-    }
-
-    @Override
-    public Object getOriginalRequest() {
-        return request;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/auth/DefaultSignerProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/DefaultSignerProvider.java
--- ./src/main/java/com/amazonaws/internal/auth/DefaultSignerProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/DefaultSignerProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,70 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.auth;
-
-import com.amazonaws.AmazonWebServiceClient;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.auth.SignerFactory;
-import com.amazonaws.auth.SignerTypeAware;
-import com.amazonaws.auth.Signer;
-import com.amazonaws.auth.SignerParams;
-import com.amazonaws.util.AwsHostNameUtils;
-
-import java.net.URI;
-
-public class DefaultSignerProvider extends SignerProvider {
-
-    private final AmazonWebServiceClient awsClient;
-    private final Signer defaultSigner;
-
-    public DefaultSignerProvider(final AmazonWebServiceClient awsClient,
-                                 final Signer defaultSigner) {
-        this.awsClient = awsClient;
-        this.defaultSigner = defaultSigner;
-    }
-
-    @Override
-    public Signer getSigner(SignerProviderContext context) {
-    Request<?> request = context.getRequest();
-        if (request == null || shouldUseDefaultSigner(request.getOriginalRequest())) {
-            if (context.isRedirect()) {
-                return awsClient.getSignerByURI(context.getUri());
-            }
-            return defaultSigner;
-        }
-
-        SignerTypeAware signerTypeAware = (SignerTypeAware) request.getOriginalRequest();
-        SignerParams params = new SignerParams(awsClient.getServiceName(), getSigningRegionForRequestURI(request.getEndpoint()));
-        return SignerFactory.createSigner(signerTypeAware.getSignerType(), params);
-    }
-
-    private boolean shouldUseDefaultSigner(AmazonWebServiceRequest originalRequest) {
-        return !(originalRequest instanceof SignerTypeAware) || isSignerOverridden();
-    }
-
-    private boolean isSignerOverridden() {
-        return awsClient.getSignerOverride() != null;
-    }
-
-    private String getSigningRegionForRequestURI(URI uri) {
-        String regionName = awsClient.getSignerRegionOverride();
-        if (regionName == null) {
-            regionName = AwsHostNameUtils.parseRegion(uri.getHost(), awsClient.getEndpointPrefix());
-        }
-        return regionName;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/auth/NoOpSignerProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/NoOpSignerProvider.java
--- ./src/main/java/com/amazonaws/internal/auth/NoOpSignerProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/NoOpSignerProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,36 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.auth;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.auth.NoOpSigner;
-import com.amazonaws.auth.Signer;
-
-@SdkInternalApi
-public class NoOpSignerProvider extends SignerProvider {
-
-    private Signer signer;
-
-    public NoOpSignerProvider() {
-        this.signer = new NoOpSigner();
-    }
-
-    @Override
-    public Signer getSigner(SignerProviderContext context) {
-        return signer;
-    }
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/auth/SignerProviderContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/SignerProviderContext.java
--- ./src/main/java/com/amazonaws/internal/auth/SignerProviderContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/SignerProviderContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,92 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.auth;
-
-import com.amazonaws.Request;
-import com.amazonaws.RequestConfig;
-
-import java.net.URI;
-
-public class SignerProviderContext {
-
-    private final URI uri;
-    private final boolean isRedirect;
-    private final Request<?> request;
-    private final RequestConfig requestConfig;
-
-    private SignerProviderContext(Builder builder) {
-        this.uri = builder.uri;
-        this.isRedirect = builder.isRedirect;
-        this.request = builder.request;
-        this.requestConfig = builder.requestConfig;
-    }
-
-    public URI getUri() {
-        return uri;
-    }
-
-    public boolean isRedirect() {
-        return isRedirect;
-    }
-
-    public Request<?> getRequest() {
-        return request;
-    }
-
-    public RequestConfig getRequestConfig() {
-        return requestConfig;
-    }
-
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    public static class Builder {
-
-        private Builder() {
-        }
-
-        private URI uri;
-        private boolean isRedirect;
-        private Request<?> request;
-        private RequestConfig requestConfig;
-
-        public Builder withUri(final URI uri) {
-            this.uri = uri;
-            return this;
-        }
-
-        public Builder withIsRedirect(final boolean withIsRedirect) {
-            this.isRedirect = withIsRedirect;
-            return this;
-        }
-
-        public Builder withRequest(final Request<?> request) {
-            this.request = request;
-            return this;
-        }
-
-        public Builder withRequestConfig(final RequestConfig requestConfig) {
-            this.requestConfig = requestConfig;
-            return this;
-        }
-
-        public SignerProviderContext build() {
-            return new SignerProviderContext(this);
-        }
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/auth/SignerProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/SignerProvider.java
--- ./src/main/java/com/amazonaws/internal/auth/SignerProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/auth/SignerProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,23 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.auth;
-
-import com.amazonaws.auth.Signer;
-
-public abstract class SignerProvider {
-
-    public abstract Signer getSigner(SignerProviderContext context);
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/BoundedLinkedHashMap.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/BoundedLinkedHashMap.java
--- ./src/main/java/com/amazonaws/internal/BoundedLinkedHashMap.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/BoundedLinkedHashMap.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,48 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * A bounded linked hash map that would remove the eldest entry when the map
- * size exceeds a configurable maximum.
- */
-final class BoundedLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
-    private static final long serialVersionUID = 1L;
-    private final int maxSize;
-    BoundedLinkedHashMap(int maxSize) {
-        this.maxSize = maxSize;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * Returns true if the size of this map exceeds the maximum.
-     */
-    @Override
-    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
-        return size() > maxSize;
-    }
-
-    /**
-     * Returns the maximum size of this map beyond which the eldest entry
-     * will get removed.
-     */
-    int getMaxSize() {
-        return maxSize;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/awssdk_config_default.json /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/awssdk_config_default.json
--- ./src/main/java/com/amazonaws/internal/config/awssdk_config_default.json	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/awssdk_config_default.json	1969-12-31 16:00:00.000000000 -0800
@@ -1,156 +0,0 @@
-{ // AWS Java SDK internal configuration
-  "defaultSigner" : {
-    "signerType" : "AWS4SignerType"
-  },
-  // "regionSigners" configuration takes precedence over
-  // the "serviceSigners" configuration,
-  // but not the "serviceRegionSigners" configuration
-  "serviceSigners" : [ {
-    "key" : "importexport",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "s3",
-    "config" : {
-      "signerType" : "AWSS3V4SignerType"
-    }
-  } ],
-  "regionSigners" : [ ],
-  "serviceRegionSigners" : [ {
-    "key" : "sdb/us-east-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/us-west-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/us-west-2",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/eu-west-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/ap-southeast-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/ap-southeast-2",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/ap-northeast-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/sa-east-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  }, {
-    "key" : "sdb/us-gov-west-1",
-    "config" : {
-      "signerType" : "QueryStringSignerType"
-    }
-  } ],
-  // AWS http client internal configuration.
-  // Currently, only those http client with class name not following the usual
-  // convention of (Amazon|AWS).*(JavaClient|Client)
-  // needs to be explicitly configured.  Otherwise, the service name of an
-  // http client not explicitly configured will be derived automatically from
-  // the class name by removing the prefix and suffix as necessary.
-  "httpClients" : [ {
-    "key" : "AmazonSimpleWorkflowClient",
-    "config" : {
-      "serviceName" : "swf"
-    }
-  }, {
-    "key" : "AmazonCloudWatchClient",
-    "config" : {
-      "serviceName" : "monitoring"
-    }
-  }, {
-    "key" : "DataPipelineClient",
-    "config" : {
-      "serviceName" : "datapipeline"
-    }
-  }, {
-    "key" : "AmazonIdentityManagementClient",
-    "config" : {
-      "serviceName" : "iam"
-    }
-  }, {
-    "key" : "AmazonSimpleDBClient",
-    "config" : {
-      "serviceName" : "sdb"
-    }
-  }, {
-    "key" : "AmazonSimpleEmailServiceClient",
-    "config" : {
-      "serviceName" : "email",
-      "regionMetadataServiceName": "email" // for region metadata
-    }
-  }, {
-    "key" : "AWSSecurityTokenServiceClient",
-    "config" : {
-      "serviceName" : "sts"
-    }
-  }, {
-    "key" : "AmazonCognitoIdentityClient",
-    "config" : {
-      "serviceName" : "cognito-identity"
-    }
-  }, {
-    "key" : "AmazonCognitoSyncClient",
-    "config" : {
-      "serviceName" : "cognito-sync"
-    }
-  }, {
-    "key": "AmazonCloudSearchDomainClient",
-    "config" : {
-      "serviceName": "cloudsearch"
-    }
-  }, {
-    "key": "AWSSimpleSystemsManagementClient",
-    "config" : {
-      "serviceName": "ssm"
-    }
-  }, {
-    "key": "AWSDirectoryServiceClient",
-    "config" : {
-      "serviceName": "ds"
-    }
-  }, {
-    "key": "AmazonDynamoDBStreamsClient",
-    "config" : {
-      "serviceName": "dynamodb", // for v4 signing
-      "regionMetadataServiceName": "streams.dynamodb" // for region metadata
-    }
-  }, {
-    "key" : "AWSIotClient",
-    "config" : {
-      "regionMetadataServiceName": "iot" // for region metadata
-    }
-  } ],
-  "hostRegexToRegionMappings" : [ {
-    "hostNameRegex" : "(.+\\.)?s3\\.amazonaws\\.com",
-    "regionName"    : "us-east-1"
-  }, {
-    "hostNameRegex" : "(.+\\.)?s3-external-1\\.amazonaws\\.com",
-    "regionName"    : "us-east-1"
-  }, {
-    "hostNameRegex" : "(.+\\.)?s3-fips-us-gov-west-1\\.amazonaws\\.com",
-    "regionName"    : "us-gov-west-1"
-  } ],
-  "userAgentTemplate": "aws-sdk-{platform}/{version} {os.name}/{os.version} {java.vm.name}/{java.vm.version} java/{java.version}{language.and.region}{additional.languages}"
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/Builder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/Builder.java
--- ./src/main/java/com/amazonaws/internal/config/Builder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/Builder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-public interface Builder<T> {
-    public T build();
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/HostRegexToRegionMapping.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HostRegexToRegionMapping.java
--- ./src/main/java/com/amazonaws/internal/config/HostRegexToRegionMapping.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HostRegexToRegionMapping.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,58 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import com.amazonaws.annotation.Immutable;
-
-@Immutable
-public class HostRegexToRegionMapping {
-
-    private final String regionName;
-    private final Pattern hostNameRegexPattern;
-
-    public HostRegexToRegionMapping(
-            String hostNameRegex, String regionName) {
-        if (hostNameRegex == null || hostNameRegex.isEmpty()) {
-            throw new IllegalArgumentException(
-                    "Invalid HostRegexToRegionMapping configuration: " +
-                    "hostNameRegex must be non-empty");
-        }
-        try {
-            this.hostNameRegexPattern = Pattern.compile(hostNameRegex);
-        } catch (PatternSyntaxException e) {
-            throw new IllegalArgumentException(
-                    "Invalid HostRegexToRegionMapping configuration: " +
-                    "hostNameRegex is not a valid regex",
-                    e);
-        }
-        if (regionName == null || regionName.isEmpty()) {
-            throw new IllegalArgumentException(
-                    "Invalid HostRegexToRegionMapping configuration: " +
-                    "regionName must be non-empty");
-        }
-        this.regionName = regionName;
-    }
-
-    public String getRegionName() {
-        return regionName;
-    }
-    
-    public boolean isHostNameMatching(String hostname) {
-    	return hostNameRegexPattern.matcher(hostname).matches();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/HostRegexToRegionMappingJsonHelper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HostRegexToRegionMappingJsonHelper.java
--- ./src/main/java/com/amazonaws/internal/config/HostRegexToRegionMappingJsonHelper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HostRegexToRegionMappingJsonHelper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-/**
- * Builder class for HostRegexToRegionMapping which exposes its property
- * setters.
- */
-public class HostRegexToRegionMappingJsonHelper implements Builder<HostRegexToRegionMapping> {
-
-    private String hostNameRegex;
-    private String regionName;
-
-    public HostRegexToRegionMappingJsonHelper() {}
-
-    public String getHostNameRegex() {
-        return hostNameRegex;
-    }
-
-    public void setHostNameRegex(String hostNameRegex) {
-        this.hostNameRegex = hostNameRegex;
-    }
-
-    public String getRegionName() {
-        return regionName;
-    }
-
-    public void setRegionName(String regionName) {
-        this.regionName = regionName;
-    }
-
-    @Override
-    public HostRegexToRegionMapping build() {
-        return new HostRegexToRegionMapping(hostNameRegex, regionName);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/HttpClientConfig.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HttpClientConfig.java
--- ./src/main/java/com/amazonaws/internal/config/HttpClientConfig.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HttpClientConfig.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,62 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-import com.amazonaws.annotation.Immutable;
-
-/**
- * AWS HttpClient configuration.
- */
-@Immutable
-public class HttpClientConfig {
-    // This class is not strictly necessary for the existing use cases,
-    // but allows future expansion of additional configurations to be made
-    // with ease.
-    private final String serviceName;
-    private final String regionMetadataServiceName;
-
-    /**
-     * @param serviceName
-     *            The service name used for request signing. It's also used as
-     *            the service identifier when looking up the region metadata if
-     *            regionMetadataServiceName is not set.
-     * @param regionMetadataServiceName
-     *            Override value for the service name identifier when looking up
-     *            the region metadata. This config is normally needed in
-     *            scenarios when a common sigv4 service name is shared by
-     *            multiple services that have different region metadata (for
-     *            example, AmazonDynamoDBClient and AmazonDynamoDBStreamsClient
-     *            share the same service name 'dynamodb' but not the same
-     *            endpoint prefix).
-     */
-    HttpClientConfig(String serviceName, String regionMetadataServiceName) {
-        this.serviceName = serviceName;
-        this.regionMetadataServiceName = regionMetadataServiceName;
-    }
-
-    @Override public String toString() {
-        return "serviceName: " + serviceName + ", regionMetadataServiceName: "
-                + regionMetadataServiceName;
-    }
-
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    public String getRegionMetadataServiceName() {
-        return regionMetadataServiceName;
-    }
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/HttpClientConfigJsonHelper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HttpClientConfigJsonHelper.java
--- ./src/main/java/com/amazonaws/internal/config/HttpClientConfigJsonHelper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/HttpClientConfigJsonHelper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-/**
- * An internal class used to build {@link HttpClientConfig} after this class per se has been
- * unmarshalled from JSON. This class allows us to make use of Jackson without the need to write any
- * special parser or json marshaller/unmarshaller.
- */
-public class HttpClientConfigJsonHelper implements Builder<HttpClientConfig> {
-
-    private String serviceName;
-    private String regionMetadataServiceName;
-
-    public HttpClientConfigJsonHelper() {
-    }
-
-    public HttpClientConfigJsonHelper(String serviceName, String regionMetadataServiceName) {
-        this.serviceName = serviceName;
-        this.regionMetadataServiceName = regionMetadataServiceName;
-    }
-
-    @Override
-    public String toString() {
-        return "serviceName: " + serviceName + ", regionMetadataServiceName: " + regionMetadataServiceName;
-    }
-
-    public String getServiceName() {
-        return serviceName;
-    }
-
-    public void setServiceName(String serviceName) {
-        this.serviceName = serviceName;
-    }
-
-    public String getRegionMetadataServiceName() {
-        return regionMetadataServiceName;
-    }
-
-    public void setRegionMetadataServiceName(String regionMetadataServiceName) {
-        this.regionMetadataServiceName = regionMetadataServiceName;
-    }
-
-    @Override
-    public HttpClientConfig build() {
-        return new HttpClientConfig(serviceName, regionMetadataServiceName);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/InternalConfig.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/InternalConfig.java
--- ./src/main/java/com/amazonaws/internal/config/InternalConfig.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/InternalConfig.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,320 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import com.amazonaws.annotation.Immutable;
-import com.amazonaws.log.InternalLogApi;
-import com.amazonaws.log.InternalLogFactory;
-import com.amazonaws.util.ClassLoaderHelper;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.MapperFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * Internal configuration for the AWS Java SDK.
- */
-@Immutable
-public class InternalConfig {
-
-    //@formatter:off
-    private static final ObjectMapper MAPPER = new ObjectMapper()
-            .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
-            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
-            .configure(JsonParser.Feature.ALLOW_COMMENTS, true);
-    //@formatter:on
-
-    private static final InternalLogApi log = InternalLogFactory.getLog(InternalConfig.class);
-
-    static final String DEFAULT_CONFIG_RESOURCE_RELATIVE_PATH = "awssdk_config_default.json";
-    static final String DEFAULT_CONFIG_RESOURCE_ABSOLUTE_PATH = "/com/amazonaws/internal/config/"
-            + DEFAULT_CONFIG_RESOURCE_RELATIVE_PATH;
-
-    static final String CONFIG_OVERRIDE_RESOURCE = "awssdk_config_override.json";
-    private static final String SERVICE_REGION_DELIMITOR = "/";
-
-    private final SignerConfig defaultSignerConfig;
-    private final Map<String, SignerConfig> serviceRegionSigners;
-    private final Map<String, SignerConfig> regionSigners;
-    private final Map<String, SignerConfig> serviceSigners;
-    private final Map<String, HttpClientConfig> httpClients;
-
-    private final List<HostRegexToRegionMapping> hostRegexToRegionMappings;
-
-    private final String userAgentTemplate;
-
-    /**
-     * @param defaults
-     *            default configuration
-     * @param override
-     *            override configuration
-     */
-    InternalConfig(InternalConfigJsonHelper defaults, InternalConfigJsonHelper override) {
-        SignerConfigJsonHelper scb = defaults.getDefaultSigner();
-        this.defaultSignerConfig = scb == null ? null : scb.build();
-
-        regionSigners = mergeSignerMap(defaults.getRegionSigners(), override.getRegionSigners(), "region");
-        serviceSigners = mergeSignerMap(defaults.getServiceSigners(), override.getServiceSigners(), "service");
-        serviceRegionSigners = mergeSignerMap(defaults.getServiceRegionSigners(), override.getServiceRegionSigners(),
-                "service" + SERVICE_REGION_DELIMITOR + "region");
-        httpClients = merge(defaults.getHttpClients(), override.getHttpClients());
-
-        hostRegexToRegionMappings = append(override.getHostRegexToRegionMappings(),
-                defaults.getHostRegexToRegionMappings());
-
-        if (override.getUserAgentTemplate() != null) {
-            userAgentTemplate = override.getUserAgentTemplate();
-        } else {
-            userAgentTemplate = defaults.getUserAgentTemplate();
-        }
-    }
-
-    /**
-     * Returns an immutable map by merging the override signer configuration into the default signer
-     * configuration for the given theme.
-     *
-     * @param defaults
-     *            default signer configuration
-     * @param override
-     *            signer configurations overrides
-     * @param theme
-     *            used for message logging. eg region, service, region+service
-     */
-    private Map<String, SignerConfig> mergeSignerMap(JsonIndex<SignerConfigJsonHelper, SignerConfig>[] defaults,
-                                                     JsonIndex<SignerConfigJsonHelper, SignerConfig>[] overrides,
-                                                     String theme) {
-        Map<String, SignerConfig> map = buildSignerMap(defaults, theme);
-        Map<String, SignerConfig> mapOverride = buildSignerMap(overrides, theme);
-        map.putAll(mapOverride);
-        return Collections.unmodifiableMap(map);
-    }
-
-    private <C extends Builder<T>, T> Map<String, T> merge(JsonIndex<C, T>[] defaults, JsonIndex<C, T>[] overrides) {
-        Map<String, T> map = buildMap(defaults);
-        Map<String, T> mapOverride = buildMap(overrides);
-        map.putAll(mapOverride);
-        return Collections.unmodifiableMap(map);
-    }
-
-    private <C extends Builder<T>, T> Map<String, T> buildMap(JsonIndex<C, T>[] signerIndexes) {
-        Map<String, T> map = new HashMap<String, T>();
-        if (signerIndexes != null) {
-            for (JsonIndex<C, T> index : signerIndexes) {
-                String region = index.getKey();
-                T prev = map.put(region, index.newReadOnlyConfig());
-                if (prev != null) {
-                    log.warn("Duplicate definition of signer for " + index.getKey());
-                }
-            }
-        }
-        return map;
-    }
-
-    private <C extends Builder<T>, T> List<T> append(C[] defaults, C[] overrides) {
-        List<T> list = new LinkedList<T>();
-        if (defaults != null) {
-            for (C builder : defaults) {
-                list.add(builder.build());
-            }
-        }
-        if (overrides != null) {
-            for (C builder : overrides) {
-                list.add(builder.build());
-            }
-        }
-        return list;
-    }
-
-    /**
-     * Builds and returns a signer configuration map.
-     *
-     * @param signerIndexes
-     *            signer configuration entries loaded from JSON
-     * @param theme
-     *            used for message logging. eg region, service, region+service
-     */
-    private Map<String, SignerConfig> buildSignerMap(JsonIndex<SignerConfigJsonHelper, SignerConfig>[] signerIndexes,
-                                                     String theme) {
-        Map<String, SignerConfig> map = new HashMap<String, SignerConfig>();
-        if (signerIndexes != null) {
-            for (JsonIndex<SignerConfigJsonHelper, SignerConfig> index : signerIndexes) {
-                String region = index.getKey();
-                SignerConfig prev = map.put(region, index.newReadOnlyConfig());
-                if (prev != null) {
-                    log.warn("Duplicate definition of signer for " + theme + " " + index.getKey());
-                }
-            }
-        }
-        return map;
-    }
-
-    /**
-     * Returns the signer configuration for the specified service, not specific to any region.
-     */
-    public SignerConfig getSignerConfig(String serviceName) {
-        return getSignerConfig(serviceName, null);
-    }
-
-    /**
-     * Returns the http client configuration for the http client name.
-     */
-    public HttpClientConfig getHttpClientConfig(String httpClientName) {
-        return httpClients.get(httpClientName);
-    }
-
-    /**
-     * Returns the signer configuration for the specified service name and an optional region name.
-     * 
-     * @param serviceName
-     *            must not be null
-     * @param regionName
-     *            similar to the region name in <code>Regions</code>; can be null.
-     * @return the signer
-     */
-    public SignerConfig getSignerConfig(String serviceName, String regionName) {
-        if (serviceName == null)
-            throw new IllegalArgumentException();
-        SignerConfig signerConfig = null;
-        if (regionName != null) {
-            // Service+Region signer config has the highest precedence
-            String key = serviceName + SERVICE_REGION_DELIMITOR + regionName;
-            signerConfig = serviceRegionSigners.get(key);
-            if (signerConfig != null) {
-                return signerConfig;
-            }
-            // Region signer config has the 2nd highest precedence
-            signerConfig = regionSigners.get(regionName);
-            if (signerConfig != null) {
-                return signerConfig;
-            }
-        }
-        // Service signer config has the 3rd highest precedence
-        signerConfig = serviceSigners.get(serviceName);
-        // Fall back to the default
-        return signerConfig == null ? defaultSignerConfig : signerConfig;
-    }
-
-    /**
-     * @return all the host-name-regex to region-name mappings.
-     */
-    public List<HostRegexToRegionMapping> getHostRegexToRegionMappings() {
-        return Collections.unmodifiableList(hostRegexToRegionMappings);
-    }
-
-    /**
-     * @return the custom user agent template, if configured
-     */
-    public String getUserAgentTemplate() {
-        return userAgentTemplate;
-    }
-
-    static InternalConfigJsonHelper loadfrom(URL url) throws JsonParseException, JsonMappingException, IOException {
-        if (url == null)
-            throw new IllegalArgumentException();
-        InternalConfigJsonHelper target = MAPPER.readValue(url, InternalConfigJsonHelper.class);
-        return target;
-    }
-
-    /**
-     * Loads and returns the AWS Java SDK internal configuration from the classpath.
-     */
-    static InternalConfig load() throws JsonParseException, JsonMappingException, IOException {
-        // First try loading via the class by using a relative path
-        URL url = ClassLoaderHelper.getResource(DEFAULT_CONFIG_RESOURCE_RELATIVE_PATH, true, InternalConfig.class); // classesFirst=true
-        if (url == null) { // Then try with the absolute path
-            url = ClassLoaderHelper.getResource(DEFAULT_CONFIG_RESOURCE_ABSOLUTE_PATH, InternalConfig.class);
-        }
-        InternalConfigJsonHelper config = loadfrom(url);
-        InternalConfigJsonHelper configOverride;
-        URL overrideUrl = ClassLoaderHelper.getResource("/" + CONFIG_OVERRIDE_RESOURCE, InternalConfig.class);
-        if (overrideUrl == null) { // Try without a leading "/"
-            overrideUrl = ClassLoaderHelper.getResource(CONFIG_OVERRIDE_RESOURCE, InternalConfig.class);
-        }
-        if (overrideUrl == null) {
-            log.debug("Configuration override " + CONFIG_OVERRIDE_RESOURCE + " not found.");
-            configOverride = new InternalConfigJsonHelper();
-        } else {
-            configOverride = loadfrom(overrideUrl);
-        }
-        InternalConfig merged = new InternalConfig(config, configOverride);
-        merged.setDefaultConfigFileLocation(url);
-        merged.setOverrideConfigFileLocation(overrideUrl);
-        return merged;
-    }
-
-    /*
-     * For debugging purposes
-     */
-
-    private URL defaultConfigFileLocation;
-    private URL overrideConfigFileLocation;
-
-    public URL getDefaultConfigFileLocation() {
-        return defaultConfigFileLocation;
-    }
-
-    public URL getOverrideConfigFileLocation() {
-        return overrideConfigFileLocation;
-    }
-
-    void setDefaultConfigFileLocation(URL url) {
-        this.defaultConfigFileLocation = url;
-    }
-
-    void setOverrideConfigFileLocation(URL url) {
-        this.overrideConfigFileLocation = url;
-    }
-
-    void dump() {
-        StringBuilder sb = new StringBuilder().append("defaultSignerConfig: ").append(defaultSignerConfig).append("\n")
-                .append("serviceRegionSigners: ").append(serviceRegionSigners).append("\n").append("regionSigners: ")
-                .append(regionSigners).append("\n").append("serviceSigners: ").append(serviceSigners).append("\n")
-                .append("userAgentTemplate: ").append(userAgentTemplate);
-        log.debug(sb.toString());
-    }
-
-    public static class Factory {
-        private static final InternalConfig SINGELTON;
-
-        static {
-            InternalConfig config = null;
-            try {
-                config = InternalConfig.load();
-            } catch (RuntimeException ex) {
-                throw ex;
-            } catch (Exception ex) {
-                throw new IllegalStateException("Fatal: Failed to load the internal config for AWS Java SDK", ex);
-            }
-            SINGELTON = config;
-        }
-
-        /**
-         * Returns a non-null and immutable instance of the AWS SDK internal configuration.
-         */
-        public static InternalConfig getInternalConfig() {
-            return SINGELTON;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/InternalConfigJsonHelper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/InternalConfigJsonHelper.java
--- ./src/main/java/com/amazonaws/internal/config/InternalConfigJsonHelper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/InternalConfigJsonHelper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,96 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-/**
- * An internal class used to help build {@link InternalConfig} after this class per se has been
- * unmarshalled from JSON. This class allows us to make use of Jackson without the need to write any
- * special parser or json marshaller/unmarshaller.
- */
-public class InternalConfigJsonHelper {
-
-    private SignerConfigJsonHelper defaultSigner;
-
-    // Implementation note:
-    // Internally use list instead of Map for ease of implementation to
-    // leverage on Jackson which supports recursive list of arbitrary pojos
-    // without the use of custom [un]marshallers. This is not the case for
-    // Map, which Jackson only supports the use of strings
-    // without custom [un]marshaller.
-    private JsonIndex<SignerConfigJsonHelper, SignerConfig>[] serviceSigners;
-    private JsonIndex<SignerConfigJsonHelper, SignerConfig>[] regionSigners;
-    private JsonIndex<SignerConfigJsonHelper, SignerConfig>[] serviceRegionSigners;
-    private JsonIndex<HttpClientConfigJsonHelper, HttpClientConfig>[] httpClients;
-
-    private HostRegexToRegionMappingJsonHelper[] hostRegexToRegionMappings;
-
-    private String userAgentTemplate;
-
-    public SignerConfigJsonHelper getDefaultSigner() {
-        return defaultSigner;
-    }
-
-    public void setDefaultSigner(SignerConfigJsonHelper defaultSigner) {
-        this.defaultSigner = defaultSigner;
-    }
-
-    public JsonIndex<SignerConfigJsonHelper, SignerConfig>[] getServiceSigners() {
-        return serviceSigners;
-    }
-
-    public void setServiceSigners(JsonIndex<SignerConfigJsonHelper, SignerConfig>... serviceSigners) {
-        this.serviceSigners = serviceSigners;
-    }
-
-    public JsonIndex<SignerConfigJsonHelper, SignerConfig>[] getRegionSigners() {
-        return regionSigners;
-    }
-
-    public void setRegionSigners(JsonIndex<SignerConfigJsonHelper, SignerConfig>... regionSigners) {
-        this.regionSigners = regionSigners;
-    }
-
-    public JsonIndex<SignerConfigJsonHelper, SignerConfig>[] getServiceRegionSigners() {
-        return serviceRegionSigners;
-    }
-
-    public void setServiceRegionSigners(JsonIndex<SignerConfigJsonHelper, SignerConfig>... serviceRegionSigners) {
-        this.serviceRegionSigners = serviceRegionSigners;
-    }
-
-    public JsonIndex<HttpClientConfigJsonHelper, HttpClientConfig>[] getHttpClients() {
-        return httpClients;
-    }
-
-    public void setHttpClients(JsonIndex<HttpClientConfigJsonHelper, HttpClientConfig>... httpClients) {
-        this.httpClients = httpClients;
-    }
-
-    public HostRegexToRegionMappingJsonHelper[] getHostRegexToRegionMappings() {
-        return hostRegexToRegionMappings;
-    }
-
-    public void setHostRegexToRegionMappings(HostRegexToRegionMappingJsonHelper[] hostRegexToRegionMappings) {
-        this.hostRegexToRegionMappings = hostRegexToRegionMappings;
-    }
-
-    public String getUserAgentTemplate() {
-        return userAgentTemplate;
-    }
-
-    public void setUserAgentTemplate(String userAgentTemplate) {
-        this.userAgentTemplate = userAgentTemplate;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/JsonIndex.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/JsonIndex.java
--- ./src/main/java/com/amazonaws/internal/config/JsonIndex.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/JsonIndex.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-/**
- * An internal class used to represent a key-object pair for JSON persistence purposes.
- */
-public final class JsonIndex<C extends Builder<T>, T> {
-
-    private String key;
-    private C config;
-
-    public JsonIndex() {
-    }
-
-    public JsonIndex(String key) {
-        this.key = key;
-    }
-
-    public JsonIndex(String key, C config) {
-        this.key = key;
-        this.config = config;
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(String key) {
-        this.key = key;
-    }
-
-    public C getConfig() {
-        return config;
-    }
-
-    public void setConfig(C config) {
-        this.config = config;
-    }
-
-    public T newReadOnlyConfig() {
-        return config.build();
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/SignerConfig.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/SignerConfig.java
--- ./src/main/java/com/amazonaws/internal/config/SignerConfig.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/SignerConfig.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-import com.amazonaws.annotation.Immutable;
-
-/**
- * Signer configuration.
- */
-@Immutable
-public class SignerConfig {
-
-    private final String signerType;
-
-    SignerConfig(String signerType) {
-        this.signerType = signerType;
-    }
-
-    SignerConfig(SignerConfig from) {
-        this.signerType = from.getSignerType();
-    }
-
-    public String getSignerType() {
-        return signerType;
-    }
-
-    @Override
-    public String toString() {
-        return signerType;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/config/SignerConfigJsonHelper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/SignerConfigJsonHelper.java
--- ./src/main/java/com/amazonaws/internal/config/SignerConfigJsonHelper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/config/SignerConfigJsonHelper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.config;
-
-/**
- * An internal class used to build {@link SignerConfig} after this class per se has been
- * unmarshalled from JSON. This class allows us to make use of Jackson without the need to write any
- * special parser or json marshaller/unmarshaller.
- */
-public class SignerConfigJsonHelper implements Builder<SignerConfig> {
-
-    private String signerType;
-
-    public SignerConfigJsonHelper() {
-    }
-
-    public SignerConfigJsonHelper(String signerType) {
-        this.signerType = signerType;
-    }
-
-    public String getSignerType() {
-        return signerType;
-    }
-
-    public void setSignerType(String signerType) {
-        this.signerType = signerType;
-    }
-
-    @Override
-    public SignerConfig build() {
-        return new SignerConfig(signerType);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/CRC32MismatchException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CRC32MismatchException.java
--- ./src/main/java/com/amazonaws/internal/CRC32MismatchException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CRC32MismatchException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.IOException;
-
-/**
- * The exception will be thrown when client side CRC32 checksum does not match the one from server side.
- */
-public class CRC32MismatchException extends IOException {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Creates a new CRC32MismatchException with the specified message, and root
-     * cause.
-     *
-     * @param message
-     *            An error message describing why this exception was thrown.
-     * @param t
-     *            The underlying cause of this exception.
-     */
-    public CRC32MismatchException(String message, Throwable t) {
-        super(message, t);
-    }
-
-    /**
-     * Creates a new CRC32MismatchException with the specified message.
-     *
-     * @param message
-     *            An error message describing why this exception was thrown.
-     */
-    public CRC32MismatchException(String message) {
-        super(message);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/CustomBackoffStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CustomBackoffStrategy.java
--- ./src/main/java/com/amazonaws/internal/CustomBackoffStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/CustomBackoffStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-public abstract class CustomBackoffStrategy {
-    public abstract int getBackoffPeriod(int retryAttempts);
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/DateTimeJsonSerializer.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DateTimeJsonSerializer.java
--- ./src/main/java/com/amazonaws/internal/DateTimeJsonSerializer.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DateTimeJsonSerializer.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.internal;
-
-import java.io.IOException;
-
-import org.joda.time.DateTime;
-
-import com.amazonaws.util.DateUtils;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-
-/**
- * A Jackson serializer for Joda {@code DateTime}s.
- */
-public final class DateTimeJsonSerializer extends JsonSerializer<DateTime> {
-
-    @Override
-    public void serialize(
-            DateTime value,
-            JsonGenerator jgen,
-            SerializerProvider provider) throws IOException {
-
-        jgen.writeString(DateUtils.formatISO8601Date(value));
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/DefaultServiceEndpointBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DefaultServiceEndpointBuilder.java
--- ./src/main/java/com/amazonaws/internal/DefaultServiceEndpointBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DefaultServiceEndpointBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,83 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.regions.Region;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * Uses region metdata to construct an endpoint for a specific service
- */
-@NotThreadSafe
-public class DefaultServiceEndpointBuilder extends ServiceEndpointBuilder {
-
-    private static final Log log = LogFactory.getLog(DefaultServiceEndpointBuilder.class);
-
-    private final String serviceName;
-    private final String protocol;
-    private Region region;
-
-    public DefaultServiceEndpointBuilder(String serviceName, String protocol) {
-        this.serviceName = serviceName;
-        this.protocol = protocol;
-    }
-
-    public DefaultServiceEndpointBuilder withRegion(Region region) {
-        if (region == null) {
-            throw new IllegalArgumentException("Region cannot be null");
-        }
-        this.region = region;
-        return this;
-    }
-
-    @Override
-    public URI getServiceEndpoint() {
-        String serviceEndpoint = region.getServiceEndpoint(serviceName);
-
-        if (serviceEndpoint == null) {
-
-            serviceEndpoint = String.format("%s.%s.%s", serviceName, region.getName(), region.getDomain());
-
-            log.info("{" + serviceName + ", " + region.getName() + "} was not "
-                    + "found in region metadata, trying to construct an "
-                    + "endpoint using the standard pattern for this region: '" + serviceEndpoint + "'.");
-
-        }
-        return toURI(stripProtocol(serviceEndpoint));
-    }
-
-    private String stripProtocol(final String endpoint) {
-        final int protocolIndex = endpoint.indexOf("://");
-        return protocolIndex >= 0 ? endpoint.substring(protocolIndex + "://".length()) : endpoint;
-    }
-
-    private URI toURI(String endpoint) throws IllegalArgumentException {
-        try {
-            return new URI(String.format("%s://%s", protocol, endpoint));
-        } catch (URISyntaxException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    @Override
-    public Region getRegion() {
-        return region;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/DelegateInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DelegateInputStream.java
--- ./src/main/java/com/amazonaws/internal/DelegateInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DelegateInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,66 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * InputStream delegate class. Subclasses could extend this class, so that
- * they need only override methods they are interested in enhancing.
- *
- */
-public class DelegateInputStream extends InputStream {
-
-    protected final InputStream in;
-
-    public DelegateInputStream(InputStream in) {
-        this.in = in;
-    }
-
-    public int read() throws IOException {
-        return in.read();
-    }
-
-    public int read(byte b[]) throws IOException {
-        return in.read(b);
-    }
-    public int read(byte b[], int off, int len) throws IOException {
-        return in.read(b, off, len);
-    }
-
-    public long skip(long n) throws IOException {
-        return in.skip(n);
-    }
-    public int available() throws IOException {
-        return in.available();
-    }
-    public void close() throws IOException {
-        in.close();
-    }
-
-    public void mark(int readlimit) {
-        in.mark(readlimit);
-    }
-    public void reset() throws IOException {
-        in.reset();
-    }
-
-    public boolean markSupported() {
-        return in.markSupported();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/DelegateSocket.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DelegateSocket.java
--- ./src/main/java/com/amazonaws/internal/DelegateSocket.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DelegateSocket.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,245 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.channels.SocketChannel;
-
-/**
- * Socket delegate class. Subclasses could extend this class, so that
- * they only need to override methods they are interested in enhancing.
- *
- */
-public class DelegateSocket extends Socket {
-
-    protected final Socket sock;
-
-    public DelegateSocket(Socket sock) {
-        this.sock = sock;
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint) throws IOException {
-        sock.connect(endpoint);
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint, int timeout) throws IOException {
-        sock.connect(endpoint, timeout);
-    }
-
-    @Override
-    public void bind(SocketAddress bindpoint) throws IOException {
-        sock.bind(bindpoint);
-    }
-
-    @Override
-    public InetAddress getInetAddress() {
-        return sock.getInetAddress();
-    }
-
-    @Override
-    public InetAddress getLocalAddress() {
-        return sock.getLocalAddress();
-    }
-
-    @Override
-    public int getPort() {
-        return sock.getPort();
-    }
-
-    @Override
-    public int getLocalPort() {
-        return sock.getLocalPort();
-    }
-
-    @Override
-    public SocketAddress getRemoteSocketAddress() {
-        return sock.getRemoteSocketAddress();
-    }
-
-    @Override
-    public SocketAddress getLocalSocketAddress() {
-        return sock.getLocalSocketAddress();
-    }
-
-    @Override
-    public SocketChannel getChannel() {
-        return sock.getChannel();
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        return sock.getInputStream();
-    }
-
-    @Override
-    public OutputStream getOutputStream() throws IOException {
-        return sock.getOutputStream();
-    }
-
-    @Override
-    public void setTcpNoDelay(boolean on) throws SocketException {
-        sock.setTcpNoDelay(on);
-    }
-
-    @Override
-    public boolean getTcpNoDelay() throws SocketException {
-        return sock.getTcpNoDelay();
-    }
-
-    @Override
-    public void setSoLinger(boolean on, int linger) throws SocketException {
-        sock.setSoLinger(on, linger);
-    }
-
-    @Override
-    public int getSoLinger() throws SocketException {
-        return sock.getSoLinger();
-    }
-
-    @Override
-    public void sendUrgentData(int data) throws IOException {
-        sock.sendUrgentData(data);
-    }
-
-    @Override
-    public void setOOBInline(boolean on) throws SocketException {
-        sock.setOOBInline(on);
-    }
-
-    @Override
-    public boolean getOOBInline() throws SocketException {
-        return sock.getOOBInline();
-    }
-
-    @Override
-    public void setSoTimeout(int timeout) throws SocketException {
-        sock.setSoTimeout(timeout);
-    }
-
-    @Override
-    public int getSoTimeout() throws SocketException {
-        return sock.getSoTimeout();
-    }
-
-    @Override
-    public void setSendBufferSize(int size) throws SocketException {
-        sock.setSendBufferSize(size);
-    }
-
-    @Override
-    public int getSendBufferSize() throws SocketException {
-        return sock.getSendBufferSize();
-    }
-
-    @Override
-    public void setReceiveBufferSize(int size) throws SocketException {
-        sock.setReceiveBufferSize(size);
-    }
-
-    @Override
-    public int getReceiveBufferSize() throws SocketException {
-        return sock.getReceiveBufferSize();
-    }
-
-    @Override
-    public void setKeepAlive(boolean on) throws SocketException {
-        sock.setKeepAlive(on);
-    }
-
-    @Override
-    public boolean getKeepAlive() throws SocketException {
-        return sock.getKeepAlive();
-    }
-
-    @Override
-    public void setTrafficClass(int tc) throws SocketException {
-        sock.setTrafficClass(tc);
-    }
-
-    @Override
-    public int getTrafficClass() throws SocketException {
-        return sock.getTrafficClass();
-    }
-
-    @Override
-    public void setReuseAddress(boolean on) throws SocketException {
-        sock.setReuseAddress(on);
-    }
-
-    @Override
-    public boolean getReuseAddress() throws SocketException {
-        return sock.getReuseAddress();
-    }
-
-    @Override
-    public void close() throws IOException {
-        sock.close();
-    }
-
-    @Override
-    public void shutdownInput() throws IOException {
-        sock.shutdownInput();
-    }
-
-    @Override
-    public void shutdownOutput() throws IOException {
-        sock.shutdownOutput();
-    }
-
-    @Override
-    public String toString() {
-        return sock.toString();
-    }
-
-    @Override
-    public boolean isConnected() {
-        return sock.isConnected();
-    }
-
-    @Override
-    public boolean isBound() {
-        return sock.isBound();
-    }
-
-    @Override
-    public boolean isClosed() {
-        return sock.isClosed();
-    }
-
-    @Override
-    public boolean isInputShutdown() {
-        return sock.isInputShutdown();
-    }
-
-    @Override
-    public boolean isOutputShutdown() {
-        return sock.isOutputShutdown();
-    }
-
-    @Override
-    public void setPerformancePreferences(int connectionTime, int latency,
-            int bandwidth) {
-        sock.setPerformancePreferences(connectionTime, latency, bandwidth);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/DelegateSSLSocket.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DelegateSSLSocket.java
--- ./src/main/java/com/amazonaws/internal/DelegateSSLSocket.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DelegateSSLSocket.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,333 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.channels.SocketChannel;
-
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-
-public class DelegateSSLSocket extends SSLSocket {
-    protected final SSLSocket sock;
-
-    public DelegateSSLSocket(SSLSocket sock) {
-        this.sock = sock;
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint) throws IOException {
-        sock.connect(endpoint);
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint, int timeout) throws IOException {
-        sock.connect(endpoint, timeout);
-    }
-
-    @Override
-    public void bind(SocketAddress bindpoint) throws IOException {
-        sock.bind(bindpoint);
-    }
-
-    @Override
-    public InetAddress getInetAddress() {
-        return sock.getInetAddress();
-    }
-
-    @Override
-    public InetAddress getLocalAddress() {
-        return sock.getLocalAddress();
-    }
-
-    @Override
-    public int getPort() {
-        return sock.getPort();
-    }
-
-    @Override
-    public int getLocalPort() {
-        return sock.getLocalPort();
-    }
-
-    @Override
-    public SocketAddress getRemoteSocketAddress() {
-        return sock.getRemoteSocketAddress();
-    }
-
-    @Override
-    public SocketAddress getLocalSocketAddress() {
-        return sock.getLocalSocketAddress();
-    }
-
-    @Override
-    public SocketChannel getChannel() {
-        return sock.getChannel();
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        return sock.getInputStream();
-    }
-
-    @Override
-    public OutputStream getOutputStream() throws IOException {
-        return sock.getOutputStream();
-    }
-
-    @Override
-    public void setTcpNoDelay(boolean on) throws SocketException {
-        sock.setTcpNoDelay(on);
-    }
-
-    @Override
-    public boolean getTcpNoDelay() throws SocketException {
-        return sock.getTcpNoDelay();
-    }
-
-    @Override
-    public void setSoLinger(boolean on, int linger) throws SocketException {
-        sock.setSoLinger(on, linger);
-    }
-
-    @Override
-    public int getSoLinger() throws SocketException {
-        return sock.getSoLinger();
-    }
-
-    @Override
-    public void sendUrgentData(int data) throws IOException {
-        sock.sendUrgentData(data);
-    }
-
-    @Override
-    public void setOOBInline(boolean on) throws SocketException {
-        sock.setOOBInline(on);
-    }
-
-    @Override
-    public boolean getOOBInline() throws SocketException {
-        return sock.getOOBInline();
-    }
-
-    @Override
-    public void setSoTimeout(int timeout) throws SocketException {
-        sock.setSoTimeout(timeout);
-    }
-
-    @Override
-    public int getSoTimeout() throws SocketException {
-        return sock.getSoTimeout();
-    }
-
-    @Override
-    public void setSendBufferSize(int size) throws SocketException {
-        sock.setSendBufferSize(size);
-    }
-
-    @Override
-    public int getSendBufferSize() throws SocketException {
-        return sock.getSendBufferSize();
-    }
-
-    @Override
-    public void setReceiveBufferSize(int size) throws SocketException {
-        sock.setReceiveBufferSize(size);
-    }
-
-    @Override
-    public int getReceiveBufferSize() throws SocketException {
-        return sock.getReceiveBufferSize();
-    }
-
-    @Override
-    public void setKeepAlive(boolean on) throws SocketException {
-        sock.setKeepAlive(on);
-    }
-
-    @Override
-    public boolean getKeepAlive() throws SocketException {
-        return sock.getKeepAlive();
-    }
-
-    @Override
-    public void setTrafficClass(int tc) throws SocketException {
-        sock.setTrafficClass(tc);
-    }
-
-    @Override
-    public int getTrafficClass() throws SocketException {
-        return sock.getTrafficClass();
-    }
-
-    @Override
-    public void setReuseAddress(boolean on) throws SocketException {
-        sock.setReuseAddress(on);
-    }
-
-    @Override
-    public boolean getReuseAddress() throws SocketException {
-        return sock.getReuseAddress();
-    }
-
-    @Override
-    public void close() throws IOException {
-        sock.close();
-    }
-
-    @Override
-    public void shutdownInput() throws IOException {
-        sock.shutdownInput();
-    }
-
-    @Override
-    public void shutdownOutput() throws IOException {
-        sock.shutdownOutput();
-    }
-
-    @Override
-    public String toString() {
-        return sock.toString();
-    }
-
-    @Override
-    public boolean isConnected() {
-        return sock.isConnected();
-    }
-
-    @Override
-    public boolean isBound() {
-        return sock.isBound();
-    }
-
-    @Override
-    public boolean isClosed() {
-        return sock.isClosed();
-    }
-
-    @Override
-    public boolean isInputShutdown() {
-        return sock.isInputShutdown();
-    }
-
-    @Override
-    public boolean isOutputShutdown() {
-        return sock.isOutputShutdown();
-    }
-
-    @Override
-    public void setPerformancePreferences(int connectionTime, int latency,
-            int bandwidth) {
-        sock.setPerformancePreferences(connectionTime, latency, bandwidth);
-    }
-
-    @Override
-    public String[] getSupportedCipherSuites() {
-        return sock.getSupportedCipherSuites();
-    }
-
-    @Override
-    public String[] getEnabledCipherSuites() {
-        return sock.getEnabledCipherSuites();
-    }
-
-    @Override
-    public void setEnabledCipherSuites(String[] suites) {
-        sock.setEnabledCipherSuites(suites);
-    }
-
-    @Override
-    public String[] getSupportedProtocols() {
-        return sock.getSupportedProtocols();
-    }
-
-    @Override
-    public String[] getEnabledProtocols() {
-        return sock.getEnabledProtocols();
-    }
-
-    @Override
-    public void setEnabledProtocols(String[] protocols) {
-        sock.setEnabledProtocols(protocols);
-    }
-
-    @Override
-    public SSLSession getSession() {
-        return sock.getSession();
-    }
-
-    @Override
-    public void addHandshakeCompletedListener(
-            HandshakeCompletedListener listener) {
-        sock.addHandshakeCompletedListener(listener);
-    }
-
-    @Override
-    public void removeHandshakeCompletedListener(
-            HandshakeCompletedListener listener) {
-        sock.removeHandshakeCompletedListener(listener);
-    }
-
-    @Override
-    public void startHandshake() throws IOException {
-        sock.startHandshake();
-    }
-
-    @Override
-    public void setUseClientMode(boolean mode) {
-        sock.setUseClientMode(mode);
-    }
-
-    @Override
-    public boolean getUseClientMode() {
-        return sock.getUseClientMode();
-    }
-
-    @Override
-    public void setNeedClientAuth(boolean need) {
-        sock.setNeedClientAuth(need);
-    }
-
-    @Override
-    public boolean getNeedClientAuth() {
-        return sock.getNeedClientAuth();
-    }
-
-    @Override
-    public void setWantClientAuth(boolean want) {
-        sock.setWantClientAuth(want);
-    }
-
-    @Override
-    public boolean getWantClientAuth() {
-        return sock.getWantClientAuth();
-    }
-
-    @Override
-    public void setEnableSessionCreation(boolean flag) {
-        sock.setEnableSessionCreation(flag);
-    }
-
-    @Override
-    public boolean getEnableSessionCreation() {
-        return sock.getEnableSessionCreation();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/DynamoDBBackoffStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DynamoDBBackoffStrategy.java
--- ./src/main/java/com/amazonaws/internal/DynamoDBBackoffStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/DynamoDBBackoffStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,36 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-public class DynamoDBBackoffStrategy extends CustomBackoffStrategy {
-	public int getBackoffPeriod(int retries) {
-
-		if (retries <= 0) {
-			return 0;
-		} else {
-
-			int delay = 50 * (int) Math.pow(2, retries - 1);
-
-			if (delay < 0) {
-				delay = Integer.MAX_VALUE;
-			}
-
-			return delay;
-		}
-
-	}
-
-    public static final CustomBackoffStrategy DEFAULT = new DynamoDBBackoffStrategy();
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/EC2MetadataClient.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/EC2MetadataClient.java
--- ./src/main/java/com/amazonaws/internal/EC2MetadataClient.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/EC2MetadataClient.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,154 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import static com.amazonaws.SDKGlobalConfiguration.EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.util.EC2MetadataUtils;
-
-/**
- * Simple client for accessing the Amazon EC2 Instance Metadata Service.
- *
- * @deprecated Refer {@link EC2MetadataUtils}
- */
-@Deprecated
-public class EC2MetadataClient {
-
-    /** Default endpoint for the Amazon EC2 Instance Metadata Service. */
-    private static final String EC2_METADATA_SERVICE_URL = "http://169.254.169.254";
-
-    /** Default resource path for credentials in the Amazon EC2 Instance Metadata Service. */
-    public static final String SECURITY_CREDENTIALS_RESOURCE = "/latest/meta-data/iam/security-credentials/";
-
-    private static final Log log = LogFactory.getLog(EC2MetadataClient.class);
-
-    /**
-     * Connects to the Amazon EC2 Instance Metadata Service to retrieve the
-     * default credential information (if any).
-     *
-     * @return The response from the Amazon EC2 Instance Metadata Service, or
-     *         null if no credential information was available.
-     *
-     * @throws IOException
-     *             If any problems are encountered while connecting to the
-     *             Amazon EC2 Instance Metadata Service.
-     */
-    public String getDefaultCredentials() throws IOException {
-        String securityCredentialsList = readResource(SECURITY_CREDENTIALS_RESOURCE);
-
-        securityCredentialsList = securityCredentialsList.trim();
-        String[] securityCredentials = securityCredentialsList.split("\n");
-        if (securityCredentials.length == 0) return null;
-
-        String securityCredentialsName = securityCredentials[0];
-
-        return readResource(SECURITY_CREDENTIALS_RESOURCE + securityCredentialsName);
-    }
-
-    /**
-     * Connects to the metadata service to read the specified resource and
-     * returns the text contents.
-     *
-     * @param resourcePath
-     *            The resource
-     *
-     * @return The text payload returned from the Amazon EC2 Instance Metadata
-     *         service for the specified resource path.
-     *
-     * @throws IOException
-     *             If any problems were encountered while connecting to metadata
-     *             service for the requested resource path.
-     * @throws SdkClientException
-     *             If the requested metadata service is not found.
-     */
-    public String readResource(String resourcePath) throws IOException, SdkClientException {
-        URL url = getEc2MetadataServiceUrlForResource(resourcePath);
-        log.debug("Connecting to EC2 instance metadata service at URL: " + url.toString());
-
-        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
-        connection.setConnectTimeout(1000 * 2);
-        connection.setReadTimeout(1000 * 5);
-        connection.setRequestMethod("GET");
-        connection.setDoOutput(true);
-        connection.connect();
-
-        return readResponse(connection);
-    }
-
-
-    /**
-     * Reads a response from the Amazon EC2 Instance Metadata Service and
-     * returns the content as a string.
-     *
-     * @param connection
-     *            The connection to the Amazon EC2 Instance Metadata Service.
-     *
-     * @return The content contained in the response from the Amazon EC2
-     *         Instance Metadata Service.
-     *
-     * @throws IOException
-     *             If any problems ocurred while reading the response.
-     */
-    private String readResponse(HttpURLConnection connection) throws IOException {
-        if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND)
-            throw new SdkClientException("The requested metadata is not found at " + connection.getURL());
-
-        InputStream inputStream = connection.getInputStream();
-
-        try {
-            StringBuilder buffer = new StringBuilder();
-            while (true) {
-                int c = inputStream.read();
-                if (c == -1) break;
-                buffer.append((char)c);
-            }
-
-            return buffer.toString();
-        } finally {
-            inputStream.close();
-        }
-    }
-
-    /**
-     * Constructs a URL to the EC2 metadata service for the specified
-     * resource path.
-     *
-     * @param resourcePath
-     *            The resource portion of the URL.
-     *
-     * @return A URL to the EC2 metadata service for the specified resource
-     *         path.
-     *
-     * @throws IOException
-     *             If a valid URL could not be constructed.
-     */
-    private URL getEc2MetadataServiceUrlForResource(String resourcePath) throws IOException {
-        String endpoint = EC2_METADATA_SERVICE_URL;
-        if (System.getProperty(EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY) != null) {
-            endpoint = System.getProperty(EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY);
-        }
-
-        return new URL(endpoint + resourcePath);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/internal/FIFOCache.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/FIFOCache.java
--- ./src/main/java/com/amazonaws/internal/FIFOCache.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/FIFOCache.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,100 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
-
-import com.amazonaws.annotation.ThreadSafe;
-
-/**
- * A bounded cache that has a FIFO eviction policy when the cache is full.
- *
- * @param <T>
- *            value type
- */
-@ThreadSafe
-public final class FIFOCache<T> {
-    private final BoundedLinkedHashMap<String, T> map;
-    private final ReadLock rlock;
-    private final WriteLock wlock;
-
-    /**
-     * @param maxSize
-     *            the maximum number of entries of the cache
-     */
-    public FIFOCache(final int maxSize) {
-        if (maxSize < 1) {
-            throw new IllegalArgumentException("maxSize " + maxSize
-                    + " must be at least 1");
-        }
-        map = new BoundedLinkedHashMap<String, T>(maxSize);
-        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        rlock = lock.readLock();
-        wlock = lock.writeLock();
-    }
-
-    /**
-     * Adds an entry to the cache, evicting the earliest entry if necessary.
-     */
-    public T add(String key, T value) {
-        wlock.lock();
-        try {
-            return map.put(key, value);
-        } finally {
-            wlock.unlock();
-        }
-    }
-
-    /** Returns the value of the given key; or null of no such entry exists. */
-    public T get(String key) {
-        rlock.lock();
-        try {
-            return map.get(key);
-        } finally {
-            rlock.unlock();
-        }
-    }
-
-    /**
-     * Returns the current size of the cache.
-     */
-    public int size() {
-        rlock.lock();
-        try {
-            return map.size();
-        } finally {
-            rlock.unlock();
-        }
-    }
-
-    /**
-     * Returns the maximum size of the cache.
-     */
-    public int getMaxSize() {
-        return map.getMaxSize();
-    }
-
-    @Override
-    public String toString() {
-        rlock.lock();
-        try {
-            return map.toString();
-        } finally {
-            rlock.unlock();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/http/CompositeErrorCodeParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/CompositeErrorCodeParser.java
--- ./src/main/java/com/amazonaws/internal/http/CompositeErrorCodeParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/CompositeErrorCodeParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not
- * use this file except in compliance with the License. A copy of the License is
- * located at
- * 
- * http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.http;
-
-import java.util.Arrays;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.protocol.json.JsonContent;
-
-@SdkInternalApi
-public class CompositeErrorCodeParser implements ErrorCodeParser {
-    private final Iterable<ErrorCodeParser> parsers;
-
-    public CompositeErrorCodeParser(Iterable<ErrorCodeParser> parsers) {
-        this.parsers = parsers;
-    }
-
-    public CompositeErrorCodeParser(ErrorCodeParser... parsers) {
-        this.parsers = Arrays.asList(parsers);
-    }
-
-    @Override
-    public String parseErrorCode(HttpResponse response, JsonContent jsonContent) {
-        for (ErrorCodeParser parser : parsers) {
-            String errorCode = parser.parseErrorCode(response, jsonContent);
-            if (errorCode != null) {
-                return errorCode;
-            }
-        }
-
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/http/ErrorCodeParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/ErrorCodeParser.java
--- ./src/main/java/com/amazonaws/internal/http/ErrorCodeParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/ErrorCodeParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,24 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not
- * use this file except in compliance with the License. A copy of the License is
- * located at
- * 
- * http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.http;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.protocol.json.JsonContent;
-
-@SdkInternalApi
-public interface ErrorCodeParser {
-    String parseErrorCode(HttpResponse response, JsonContent jsonContent);
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/http/IonErrorCodeParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/IonErrorCodeParser.java
--- ./src/main/java/com/amazonaws/internal/http/IonErrorCodeParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/IonErrorCodeParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,75 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not
- * use this file except in compliance with the License. A copy of the License is
- * located at
- * 
- * http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.http;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.protocol.json.JsonContent;
-import com.amazonaws.util.IOUtils;
-
-import software.amazon.ion.IonReader;
-import software.amazon.ion.IonSystem;
-import software.amazon.ion.IonType;
-
-@SdkInternalApi
-public class IonErrorCodeParser implements ErrorCodeParser {
-    private static final Log log = LogFactory.getLog(IonErrorCodeParser.class);
-
-    private static final String TYPE_PREFIX = "aws-type:";
-    private static final String X_AMZN_REQUEST_ID_HEADER = "x-amzn-RequestId";
-
-    private final IonSystem ionSystem;
-
-    public IonErrorCodeParser(IonSystem ionSystem) {
-        this.ionSystem = ionSystem;
-    }
-
-    @Override
-    public String parseErrorCode(HttpResponse response, JsonContent jsonContents) {
-        IonReader reader = ionSystem.newReader(jsonContents.getRawContent());
-        try {
-            IonType type = reader.next();
-            if (type != IonType.STRUCT) {
-                throw new SdkClientException(String.format("Can only get error codes from structs (saw %s), request id %s", type, getRequestId(response)));
-            }
-
-            boolean errorCodeSeen = false;
-            String errorCode = null;
-            String[] annotations = reader.getTypeAnnotations();
-            for (String annotation : annotations) {
-                if (annotation.startsWith(TYPE_PREFIX)) {
-                    if (errorCodeSeen) {
-                        throw new SdkClientException(String.format("Multiple error code annotations found for request id %s", getRequestId(response)));
-                    } else {
-                        errorCodeSeen = true;
-                        errorCode = annotation.substring(TYPE_PREFIX.length());
-                    }
-                }
-            }
-
-            return errorCode;
-        } finally {
-            IOUtils.closeQuietly(reader, log);
-        }
-    }
-
-    private static String getRequestId(HttpResponse response) {
-        return response.getHeaders().get(X_AMZN_REQUEST_ID_HEADER);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/http/JsonErrorCodeParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/JsonErrorCodeParser.java
--- ./src/main/java/com/amazonaws/internal/http/JsonErrorCodeParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/JsonErrorCodeParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,87 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.http;
-
-import java.util.Map;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.protocol.json.JsonContent;
-import com.fasterxml.jackson.databind.JsonNode;
-
-@SdkInternalApi
-public class JsonErrorCodeParser implements ErrorCodeParser {
-
-    /**
-     * Services using AWS JSON 1.1 protocol with HTTP binding send the error code information in the
-     * response headers, instead of the content. Package private for tests.
-     */
-    static final String X_AMZN_ERROR_TYPE = "x-amzn-ErrorType";
-
-    private final String errorCodeFieldName;
-
-    public JsonErrorCodeParser() {
-        this(null);
-    }
-
-    public JsonErrorCodeParser(String errorCodeFieldName) {
-        this.errorCodeFieldName = errorCodeFieldName == null ? "__type" : errorCodeFieldName;
-    }
-
-    /**
-     * Parse the error code from the response.
-     *
-     * @return Error Code of exceptional response or null if it can't be determined
-     */
-    public String parseErrorCode(HttpResponse response, JsonContent jsonContent) {
-        String errorCodeFromHeader = parseErrorCodeFromHeader(response.getHeaders());
-        if (errorCodeFromHeader != null) {
-            return errorCodeFromHeader;
-        } else if (jsonContent != null) {
-            return parseErrorCodeFromContents(jsonContent.getJsonNode());
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Attempt to parse the error code from the response headers. Returns null if information is not
-     * present in the header.
-     */
-    private String parseErrorCodeFromHeader(Map<String, String> httpHeaders) {
-        String headerValue = httpHeaders.get(X_AMZN_ERROR_TYPE);
-        if (headerValue != null) {
-            int separator = headerValue.indexOf(':');
-            if (separator != -1) {
-                headerValue = headerValue.substring(0, separator);
-            }
-        }
-        return headerValue;
-    }
-
-    /**
-     * Attempt to parse the error code from the response content. Returns null if information is not
-     * present in the content. Codes are expected to be in the form <b>"typeName"</b> or
-     * <b>"prefix#typeName"</b> Examples : "AccessDeniedException", "com.amazonaws.dynamodb.v20111205#ProvisionedThroughputExceededException"
-     */
-    private String parseErrorCodeFromContents(JsonNode jsonContents) {
-        if (jsonContents == null || !jsonContents.has(errorCodeFieldName)) {
-            return null;
-        }
-        String code = jsonContents.findValue(errorCodeFieldName).asText();
-        int separator = code.lastIndexOf("#");
-        return code.substring(separator + 1);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/http/JsonErrorMessageParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/JsonErrorMessageParser.java
--- ./src/main/java/com/amazonaws/internal/http/JsonErrorMessageParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/http/JsonErrorMessageParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,85 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal.http;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.http.HttpResponse;
-import com.fasterxml.jackson.databind.JsonNode;
-
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-
-@SdkProtectedApi
-public class JsonErrorMessageParser {
-
-    private static final List<String> DEFAULT_ERROR_MESSAGE_LOCATIONS = Arrays
-            .asList("message", "Message", "errorMessage");
-
-    /**
-     * x-amzn-error-message may be returned by RESTFUL services that do not send a response
-     * payload (like in a HEAD request).
-     */
-    public static final String X_AMZN_ERROR_MESSAGE = "x-amzn-error-message";
-
-    /**
-     * Standard JSON Error Message Parser that checks for JSON fields in this order: 'message',
-     * 'Message', 'errorMessage'
-     */
-    public static final JsonErrorMessageParser DEFAULT_ERROR_MESSAGE_PARSER = new JsonErrorMessageParser(
-            DEFAULT_ERROR_MESSAGE_LOCATIONS);
-
-    private static final HttpResponse EMPTY_HTTP_RESPONSE = new HttpResponse(null, null);
-
-    private final List<String> errorMessageJsonLocations;
-
-    /**
-     * @param errorMessageJsonLocations JSON field locations where the parser will attempt to
-     *                                  extract the error message from.
-     */
-    public JsonErrorMessageParser(List<String> errorMessageJsonLocations) {
-        this.errorMessageJsonLocations = new LinkedList<String>(errorMessageJsonLocations);
-    }
-
-    /**
-     * @deprecated By {@link #parseErrorMessage(HttpResponse, JsonNode)}
-     */
-    @Deprecated
-    public String parseErrorMessage(JsonNode jsonNode) {
-        return parseErrorMessage(EMPTY_HTTP_RESPONSE, jsonNode);
-    }
-
-    /**
-     * Parse the error message from the response.
-     *
-     * @return Error Code of exceptional response or null if it can't be determined
-     */
-    public String parseErrorMessage(HttpResponse httpResponse, JsonNode jsonNode) {
-        // If X_AMZN_ERROR_MESSAGE is present, prefer that. Otherwise check the JSON body.
-        final String headerMessage = httpResponse.getHeader(X_AMZN_ERROR_MESSAGE);
-        if (headerMessage != null) {
-            return headerMessage;
-        }
-        for (String field : errorMessageJsonLocations) {
-            JsonNode value = jsonNode.get(field);
-            if (value != null && value.isTextual()) {
-                return value.asText();
-            }
-        }
-        return null;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/IdentityEndpointBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/IdentityEndpointBuilder.java
--- ./src/main/java/com/amazonaws/internal/IdentityEndpointBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/IdentityEndpointBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.net.URI;
-
-import com.amazonaws.regions.Region;
-
-/**
- * More of a No-Op endpoint builder that just returns the same endpoint it was constructed with
- */
-public class IdentityEndpointBuilder extends ServiceEndpointBuilder {
-
-    private final URI endpoint;
-
-    public IdentityEndpointBuilder(URI endpoint) {
-        this.endpoint = endpoint;
-    }
-
-    @Override
-    public URI getServiceEndpoint() {
-        return endpoint;
-    }
-
-    @Override
-    public DefaultServiceEndpointBuilder withRegion(Region region) {
-        // No-op
-        return null;
-    }
-
-    @Override
-    public Region getRegion() {
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/ListWithAutoConstructFlag.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ListWithAutoConstructFlag.java
--- ./src/main/java/com/amazonaws/internal/ListWithAutoConstructFlag.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ListWithAutoConstructFlag.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * List with auto construct flag to indicate whether it is auto constructed by Java SDK.
- */
-public class ListWithAutoConstructFlag<T> extends ArrayList<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Auto construct flag to indicate whether the list is auto constructed by Java SDK.
-     */
-    private boolean autoConstruct;
-
-    public ListWithAutoConstructFlag() {
-        super();
-    }
-
-    public ListWithAutoConstructFlag(Collection<? extends T> c) {
-          super(c);
-    }
-
-    public  ListWithAutoConstructFlag(int initialCapacity) {
-        super(initialCapacity);
-    }
-
-    public void setAutoConstruct(boolean autoConstruct) {
-        this.autoConstruct = autoConstruct;
-    }
-
-    /**
-     * Return true if the list is auto constructed by Java SDK
-     */
-    public boolean isAutoConstruct() {
-        return autoConstruct;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/MetricAware.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/MetricAware.java
--- ./src/main/java/com/amazonaws/internal/MetricAware.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/MetricAware.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-/**
- * Used to check if any metrics gathering activity is already turned on in one
- * of the underlying wrapped objects.
- */
-public interface MetricAware {
-    /**
-     * Returns true if this object or one of it's inner wrapped objects has
-     * metrics gathering activity turned on; false otherwise.
-     */
-    public boolean isMetricActivated();
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/MetricsInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/MetricsInputStream.java
--- ./src/main/java/com/amazonaws/internal/MetricsInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/MetricsInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,95 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.util.AWSRequestMetrics.Field;
-import com.amazonaws.util.AWSRequestMetrics;
-
-/**
- * Record input stream read time into {@link AWSRequestMetrics} under metric type
- * HttpSocketReadTime;
- */
-public class MetricsInputStream extends DelegateInputStream {
-
-    private AWSRequestMetrics metrics;
-
-    public MetricsInputStream(InputStream in) {
-        super(in);
-    }
-
-    public void setMetrics(AWSRequestMetrics metrics) {
-        this.metrics = metrics;
-    }
-
-    /**
-     * {@inheritDoc}
-     * Record the read time into the metrics.
-     */
-    @Override
-    public int read() throws IOException {
-        if (metrics != null) {
-            metrics.startEvent(Field.HttpSocketReadTime);
-        }
-        try {
-            return in.read();
-        } finally {
-            if (metrics != null) {
-                metrics.endEvent(Field.HttpSocketReadTime);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Record the read time into the metrics.
-     */
-    @Override
-    public int read(byte b[]) throws IOException {
-        if (metrics != null) {
-            metrics.startEvent(Field.HttpSocketReadTime);
-        }
-        try {
-            return in.read(b);
-        } finally {
-            if (metrics != null) {
-                metrics.endEvent(Field.HttpSocketReadTime);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * Record the read time into the metrics.
-     */
-    @Override
-    public int read(byte b[], int off, int len) throws IOException {
-        if (metrics != null) {
-            metrics.startEvent(Field.HttpSocketReadTime);
-        }
-        try {
-            return in.read(b, off, len);
-        } finally {
-            if (metrics != null) {
-                metrics.endEvent(Field.HttpSocketReadTime);
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/ReleasableInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ReleasableInputStream.java
--- ./src/main/java/com/amazonaws/internal/ReleasableInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ReleasableInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,132 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
- * for applicable license terms and NOTICE.txt for applicable notices.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import com.amazonaws.annotation.NotThreadSafe;
-
-import java.io.FileInputStream;
-import java.io.InputStream;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * An input stream that can have the close operation disabled (to avoid
- * accidentally being closed). This is necessary, for example, when an input
- * stream needs to be marked-and-reset multiple times but only as long as the
- * input stream has not been closed. To survive not being accidentally closed,
- * the close method can be disabled via {@link #disableClose()}.
- * <p>
- * The creator of this input stream should therefore always call
- * {@link #release()} in a finally block to truly release the underlying
- * resources.
- * 
- * @see Releasable
- * @see ResettableInputStream
- */
-@NotThreadSafe
-public class ReleasableInputStream extends SdkFilterInputStream implements Releasable {
-    private static final Log log = LogFactory
-            .getLog(ReleasableInputStream.class);
-    /**
-     * True if the close method is disabled; false otherwise. Default is false.
-     * In case the close method is disabled, caller would be responsible to
-     * release resources via {@link #release()}.
-     */
-    private boolean closeDisabled;
-
-    /**
-     * This constructor is not meant to be used directly. Use
-     * {@link #wrap(InputStream)} instead.
-     */
-    protected ReleasableInputStream(InputStream is) {
-        super(is);
-    }
-
-    /**
-     * If {@link #closeDisabled} is false, closes this input stream and releases
-     * any system resources associated with the stream. Otherwise, this method
-     * does nothing.
-     */
-    @Override
-    public final void close() {
-        if (!closeDisabled)
-            doRelease();
-    }
-
-    /**
-     * Closes the underlying stream file and releases any system resources associated.
-     */
-    @Override
-    public final void release() {
-        doRelease();
-    }
-
-    /**
-     * Used to truly release the underlying resources.
-     */
-    private void doRelease() {
-        try {
-            in.close();
-        } catch (Exception ex) {
-            if (log.isDebugEnabled())
-                log.debug("FYI", ex);
-        }
-        if (in instanceof Releasable) {
-            // This allows any underlying stream that has the close operation
-            // disabled to be truly released
-            Releasable r = (Releasable)in;
-            r.release();
-        }
-        abortIfNeeded();
-    }
-
-    /**
-     * Returns true if the close method has been disabled; false otherwise. Once
-     * the close method is disabled, caller would be responsible to release
-     * resources via {@link #release()}.
-     */
-    public final boolean isCloseDisabled() {
-        return closeDisabled;
-    }
-
-    /**
-     * Used to disable the close method. Once the close method is disabled,
-     * caller would be responsible to release resources via {@link #release()}.
-     */
-    public final <T extends ReleasableInputStream> T disableClose() {
-        this.closeDisabled = true;
-        @SuppressWarnings("unchecked")
-        T t = (T)this;
-        return t;
-    }
-
-    /**
-     * Wraps the given input stream into a {@link ReleasableInputStream} if
-     * necessary. Note if the given input stream is a {@link FileInputStream}, a
-     * {@link ResettableInputStream} which is a specific subclass of
-     * {@link ReleasableInputStream} will be returned.
-     */
-    public static ReleasableInputStream wrap(InputStream is) {
-        if (is instanceof ReleasableInputStream)
-            return (ReleasableInputStream)is;   // already wrapped
-        if (is instanceof FileInputStream)
-            return ResettableInputStream.newResettableInputStream((FileInputStream)is);
-        return new ReleasableInputStream(is);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/Releasable.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/Releasable.java
--- ./src/main/java/com/amazonaws/internal/Releasable.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/Releasable.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.Closeable;
-
-/**
- * Used for releasing a resource.
- * <p>
- * For example, the creation of a <code>ResettableInputStream</code> would entail
- * physically opening a file. If the opened file is meant to be closed only (in
- * a finally block) by the very same code block that created it, then it is
- * necessary that the release method must not be called while the execution is
- * made in other stack frames.
- * 
- * In such case, as other stack frames may inadvertently or indirectly call the
- * close method of the stream, the creator of the stream would need to
- * explicitly disable the accidental closing via
- * <code>ResettableInputStream#disableClose()</code>, so that the release method
- * becomes the only way to truly close the opened file.
- */
-public interface Releasable {
-    /**
-     * Releases the allocated resource. This method should not be called except
-     * by the caller who allocated the resource at the very top of the call
-     * stack. This allows, typically, a {@link Closeable} resource to be not
-     * unintentionally released owing to the calling of the
-     * {@link Closeable#close()} methods by implementation deep down in the call
-     * stack.
-     * <p>
-     * For example, the creation of a <code>ResettableInputStream</code> would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * <code>ResettableInputStream#disableClose()</code>, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public void release();
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/ResettableInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ResettableInputStream.java
--- ./src/main/java/com/amazonaws/internal/ResettableInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ResettableInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,305 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
- * for applicable license terms and NOTICE.txt for applicable notices.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.NotThreadSafe;
-
-/**
- * A mark-and-resettable input stream that can be used on files or file input
- * streams.
- * 
- * In particular, a {@link ResettableInputStream} allows the close operation to
- * be disabled via {@link #disableClose()} (to avoid accidentally being closed).
- * This is necessary when such input stream needs to be marked-and-reset
- * multiple times but only as long as the stream has not been closed.
- * <p>
- * The creator of this input stream should therefore always call
- * {@link #release()} in a finally block to truly release the underlying
- * resources.
- * 
- * @see Releasable
- */
-@NotThreadSafe
-public class ResettableInputStream extends ReleasableInputStream {
-    private static final Log log = LogFactory
-            .getLog(ResettableInputStream.class);
-    private final File file; // null if the file is not known
-    private FileInputStream fis; // never null
-    private FileChannel fileChannel; // never null
-    /**
-     * Marked position of the file; default to zero.
-     */
-    private long markPos;
-
-    /**
-     * @param file
-     *            must not be null. Upon successful construction the the file
-     *            will be opened with an input stream automatically marked at
-     *            the starting position of the given file.
-     *            <p>
-     *            Note the creation of a {@link ResettableInputStream} would
-     *            entail physically opening a file. If the opened file is meant
-     *            to be closed only (in a finally block) by the very same code
-     *            block that created it, then it is necessary that the release
-     *            method must not be called while the execution is made in other
-     *            stack frames.
-     * 
-     *            In such case, as other stack frames may inadvertently or
-     *            indirectly call the close method of the stream, the creator of
-     *            the stream would need to explicitly disable the accidental
-     *            closing via {@link ResettableInputStream#disableClose()}, so
-     *            that the release method becomes the only way to truly close
-     *            the opened file.
-     */
-    public ResettableInputStream(File file) throws IOException {
-        this(new FileInputStream(file), file);
-    }
-
-    /**
-     * @param fis
-     *            file input stream; must not be null. Upon successful
-     *            construction the input stream will be automatically marked at
-     *            the current position of the given file input stream.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public ResettableInputStream(FileInputStream fis) throws IOException {
-        this(fis, null);
-    }
-
-    /**
-     * @param file
-     *            can be null if not known
-     */
-    private ResettableInputStream(FileInputStream fis, File file) throws IOException {
-        super(fis);
-        this.file = file;
-        this.fis = fis;
-        this.fileChannel = fis.getChannel();
-        this.markPos = fileChannel.position();
-    }
-
-    @Override
-    public final boolean markSupported() {
-        return true;
-    }
-
-    /**
-     * Marks the current position in this input stream. A subsequent call to
-     * the <code>reset</code> method repositions this stream at the last marked
-     * position so that subsequent reads re-read the same bytes.
-     * This method works as long as the underlying file has not been closed.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     * 
-     * @param _
-     *            ignored
-     */
-    @Override
-    public void mark(int _) {
-        abortIfNeeded();
-        try {
-            markPos = fileChannel.position();
-        } catch (IOException e) {
-            throw new SdkClientException("Failed to mark the file position", e);
-        }
-        if (log.isTraceEnabled())
-            log.trace("File input stream marked at position " + markPos);
-    }
-
-    /**
-     * Repositions this stream to the position at the time the
-     * <code>mark</code> method was last called on this input stream.
-     * This method works as long as the underlying file has not been closed.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    @Override
-    public void reset() throws IOException {
-        abortIfNeeded();
-        fileChannel.position(markPos);
-        if (log.isTraceEnabled())
-            log.trace("Reset to position " + markPos);
-    }
-
-    @Override
-    public int available() throws IOException {
-        abortIfNeeded();
-        return fis.available();
-    }
-
-    @Override
-    public int read() throws IOException {
-        abortIfNeeded();
-        return fis.read();
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        abortIfNeeded();
-        return fis.skip(n);
-    }
-
-    @Override
-    public int read(byte[] arg0, int arg1, int arg2) throws IOException {
-        abortIfNeeded();
-        return fis.read(arg0, arg1, arg2);
-    }
-
-    /**
-     * Returns the underlying file, if known; or null if not;
-     */
-    public File getFile() {
-        return file;
-    }
-
-    /**
-     * Convenient factory method to construct a new resettable input stream for
-     * the given file, converting any IOException into SdkClientException.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public static ResettableInputStream newResettableInputStream(File file) {
-        return newResettableInputStream(file, null);
-    }
-
-    /**
-     * Convenient factory method to construct a new resettable input stream for
-     * the given file, converting any IOException into SdkClientException
-     * with the given error message.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public static ResettableInputStream newResettableInputStream(File file,
-            String errmsg) {
-        try {
-            return new ResettableInputStream(file);
-        } catch (IOException e) {
-            throw errmsg == null
-                ? new SdkClientException(e)
-                : new SdkClientException(errmsg, e);
-        }
-    }
-
-    /**
-     * Convenient factory method to construct a new resettable input stream for
-     * the given file input stream, converting any IOException into
-     * SdkClientException.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public static ResettableInputStream newResettableInputStream(
-            FileInputStream fis) {
-        return newResettableInputStream(fis, null);
-    }
-
-    /**
-     * Convenient factory method to construct a new resettable input stream for
-     * the given file input stream, converting any IOException into
-     * SdkClientException with the given error message.
-     * <p>
-     * Note the creation of a {@link ResettableInputStream} would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     * 
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * {@link ResettableInputStream#disableClose()}, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public static ResettableInputStream newResettableInputStream(
-            FileInputStream fis, String errmsg) {
-        try {
-            return new ResettableInputStream(fis);
-        } catch (IOException e) {
-            throw new SdkClientException(errmsg, e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkBufferedInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkBufferedInputStream.java
--- ./src/main/java/com/amazonaws/internal/SdkBufferedInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkBufferedInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,114 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import static com.amazonaws.util.SdkRuntime.shouldAbort;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.AbortedException;
-
-/**
- * A buffered input stream that is both SDK metric aware, and can be aborted
- * via thread interrupt.
- */
-public class SdkBufferedInputStream extends BufferedInputStream implements
-        MetricAware {
-    public SdkBufferedInputStream(InputStream in) {
-        super(in);
-    }
-
-    public SdkBufferedInputStream(InputStream in, int size) {
-        super(in, size);
-    }
-
-    @Override
-    public boolean isMetricActivated() {
-        if (in instanceof MetricAware) {
-            MetricAware metricAware = (MetricAware)in;
-            return metricAware.isMetricActivated();
-        }
-        return false;
-    }
-
-    /**
-     * Aborts with subclass specific abortion logic executed if needed.
-     * Note the interrupted status of the thread is cleared by this method.
-     * @throws AbortedException if found necessary.
-     */
-    protected final void abortIfNeeded() {
-        if (shouldAbort()) {
-            abort();    // execute subclass specific abortion logic
-            throw new AbortedException();
-        }
-    }
-
-    /**
-     * Can be used to provide abortion logic prior to throwing the
-     * AbortedException. No-op by default.
-     */
-    protected void abort() {
-    }
-
-    @Override
-    public int read() throws IOException {
-        abortIfNeeded();
-        return super.read();
-    }
-
-    @Override
-    public int read(byte b[], int off, int len) throws IOException {
-        abortIfNeeded();
-        return super.read(b, off, len);
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        abortIfNeeded();
-        return super.skip(n);
-    }
-
-    @Override
-    public int available() throws IOException {
-        abortIfNeeded();
-        return super.available();
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-        abortIfNeeded();
-    }
-
-    @Override
-    public void mark(int readlimit) {
-        abortIfNeeded();
-        super.mark(readlimit);
-    }
-
-    @Override
-    public void reset() throws IOException {
-        abortIfNeeded();
-        super.reset();
-    }
-
-    @Override
-    public boolean markSupported() {
-        abortIfNeeded();
-        return super.markSupported();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkDigestInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkDigestInputStream.java
--- ./src/main/java/com/amazonaws/internal/SdkDigestInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkDigestInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,93 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-
-/**
- * Base class for AWS Java SDK specific {@link DigestInputStream}.
- */
-public class SdkDigestInputStream extends DigestInputStream implements
-        MetricAware, Releasable {
-    private static final int SKIP_BUF_SIZE = 2*1024;
-    public SdkDigestInputStream(InputStream stream, MessageDigest digest) {
-        super(stream, digest);
-    }
-
-    @Override
-    public final boolean isMetricActivated() {
-        if (in instanceof MetricAware) {
-            MetricAware metricAware = (MetricAware)in;
-            return metricAware.isMetricActivated();
-        }
-        return false;
-    }
-
-    // https://github.com/aws/aws-sdk-java/issues/232
-    /**
-     * Skips over and discards <code>n</code> bytes of data from this input
-     * stream, while taking the skipped bytes into account for digest
-     * calculation. The <code>skip</code> method may, for a variety of reasons,
-     * end up skipping over some smaller number of bytes, possibly
-     * <code>0</code>. This may result from any of a number of conditions;
-     * reaching end of file before <code>n</code> bytes have been skipped is
-     * only one possibility. The actual number of bytes skipped is returned. If
-     * <code>n</code> is negative, no bytes are skipped.
-     *
-     * <p>
-     * The <code>skip</code> method of this class creates a byte array and then
-     * repeatedly reads into it until <code>n</code> bytes have been read or the
-     * end of the stream has been reached. Subclasses are encouraged to provide
-     * a more efficient implementation of this method. For instance, the
-     * implementation may depend on the ability to seek.
-     *
-     * @param n
-     *            the number of bytes to be skipped.
-     * @return the actual number of bytes skipped.
-     * @exception IOException
-     *                if the stream does not support seek, or if some other I/O
-     *                error occurs.
-     */
-    @Override
-    public final long skip(final long n) throws IOException {
-        if (n <= 0)
-            return n;
-        byte[] b = new byte[(int)Math.min(SKIP_BUF_SIZE, n)];
-        long m = n; // remaining number of bytes to read
-        while (m > 0) {
-            int len = read(b, 0, (int)Math.min(m, b.length));
-            if (len == -1)
-                return n - m;
-            m -= len;
-        }
-        assert (m == 0);
-        return n;
-    }
-
-    @Override
-    public final void release() {
-        // Don't call IOUtils.release(in, null) or else could lead to infinite loop
-        SdkIOUtils.closeQuietly(this);
-        if (in instanceof Releasable) {
-            // This allows any underlying stream that has the close operation
-            // disabled to be truly released
-            Releasable r = (Releasable)in;
-            r.release();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkFilterInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkFilterInputStream.java
--- ./src/main/java/com/amazonaws/internal/SdkFilterInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkFilterInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,132 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import static com.amazonaws.util.SdkRuntime.shouldAbort;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.AbortedException;
-
-/**
- * Base class for AWS Java SDK specific {@link FilterInputStream}.
- */
-public class SdkFilterInputStream extends FilterInputStream implements
-        MetricAware, Releasable {
-    private volatile boolean aborted = false;
-
-    protected SdkFilterInputStream(InputStream in) {
-        super(in);
-    }
-
-    @Override
-    public boolean isMetricActivated() {
-        if (in instanceof MetricAware) {
-            MetricAware metricAware = (MetricAware)in;
-            return metricAware.isMetricActivated();
-        }
-        return false;
-    }
-
-    /**
-     * Aborts with subclass specific abortion logic executed if needed.
-     * Note the interrupted status of the thread is cleared by this method.
-     * @throws AbortedException if found necessary.
-     */
-    protected final void abortIfNeeded() {
-        if (shouldAbort()) {
-            abort();    // execute subclass specific abortion logic
-            throw new AbortedException();
-        }
-    }
-
-    /**
-     * Can be used to provide abortion logic prior to throwing the
-     * AbortedException. If the wrapped {@code InputStream} is also an instance
-     * of this class, then it will also be aborted, otherwise this is a no-op.
-     */
-    public void abort() {
-        if (in instanceof SdkFilterInputStream) {
-            ((SdkFilterInputStream) in).abort();
-        }
-        aborted = true;
-    }
-
-    protected boolean isAborted() {
-        return aborted;
-    }
-
-    @Override
-    public int read() throws IOException {
-        abortIfNeeded();
-        return in.read();
-    }
-
-    @Override
-    public int read(byte b[], int off, int len) throws IOException {
-        abortIfNeeded();
-        return in.read(b, off, len);
-    }
-
-    @Override
-    public long skip(long n) throws IOException {
-        abortIfNeeded();
-        return in.skip(n);
-    }
-
-    @Override
-    public int available() throws IOException {
-        abortIfNeeded();
-        return in.available();
-    }
-
-    @Override
-    public void close() throws IOException {
-        in.close();
-        abortIfNeeded();
-    }
-
-    @Override
-    public synchronized void mark(int readlimit) {
-        abortIfNeeded();
-        in.mark(readlimit);
-    }
-
-    @Override
-    public synchronized void reset() throws IOException {
-        abortIfNeeded();
-        in.reset();
-    }
-
-    @Override
-    public boolean markSupported() {
-        abortIfNeeded();
-        return in.markSupported();
-    }
-
-    @Override
-    public void release() {
-        // Don't call IOUtils.release(in, null) or else could lead to infinite loop
-        SdkIOUtils.closeQuietly(this);
-        if (in instanceof Releasable) {
-            // This allows any underlying stream that has the close operation
-            // disabled to be truly released
-            Releasable r = (Releasable)in;
-            r.release();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkFilterOutputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkFilterOutputStream.java
--- ./src/main/java/com/amazonaws/internal/SdkFilterOutputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkFilterOutputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,51 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.FilterOutputStream;
-import java.io.OutputStream;
-
-import com.amazonaws.util.IOUtils;
-
-/**
- * Base class for AWS Java SDK specific {@link FilterOutputStream}.
- */
-public class SdkFilterOutputStream extends FilterOutputStream implements
-        MetricAware, Releasable {
-    public SdkFilterOutputStream(OutputStream out) {
-        super(out);
-    }
-
-    @Override
-    public boolean isMetricActivated() {
-        if (out instanceof MetricAware) {
-            MetricAware metricAware = (MetricAware)out;
-            return metricAware.isMetricActivated();
-        }
-        return false;
-    }
-
-    @Override
-    public final void release() {
-        // Don't call IOUtils.release(in, null) or else could lead to infinite loop
-        IOUtils.closeQuietly(this, null);
-        if (out instanceof Releasable) {
-            // This allows any underlying stream that has the close operation
-            // disabled to be truly released
-            Releasable r = (Releasable)out;
-            r.release();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkFunction.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkFunction.java
--- ./src/main/java/com/amazonaws/internal/SdkFunction.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkFunction.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-/**
- * Similar to the Function functional interface in Java 8.
- *
- * @param <Input>  Input type
- * @param <Output> Output type
- */
-public interface SdkFunction<Input, Output> {
-
-    Output apply(Input input);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkInputStream.java
--- ./src/main/java/com/amazonaws/internal/SdkInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,90 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import static com.amazonaws.util.SdkRuntime.shouldAbort;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.AbortedException;
-import com.amazonaws.util.IOUtils;
-
-/**
- * Base class for AWS Java SDK specific {@link InputStream}.
- */
-public abstract class SdkInputStream extends InputStream implements
-        MetricAware, Releasable {
-    /**
-     * Returns the underlying input stream, if any, from the subclass; or null
-     * if there is no underlying input stream.
-     */
-    abstract protected InputStream getWrappedInputStream();
-
-    @Override
-    public final boolean isMetricActivated() {
-        InputStream in = getWrappedInputStream();
-        if (in instanceof MetricAware) {
-            MetricAware metricAware = (MetricAware)in;
-            return metricAware.isMetricActivated();
-        }
-        return false;
-    }
-
-    /**
-     * Aborts with subclass specific abortion logic executed if needed.
-     * Note the interrupted status of the thread is cleared by this method.
-     * @throws AbortedException if found necessary.
-     */
-    protected final void abortIfNeeded() {
-        if (shouldAbort()) {
-            try {
-                abort();    // execute subclass specific abortion logic
-            } catch (IOException e) {
-                LogFactory.getLog(getClass()).debug("FYI", e);
-            }
-            throw new AbortedException();
-        }
-    }
-
-    /**
-     * Can be used to provide abortion logic prior to throwing the
-     * AbortedException. No-op by default.
-     */
-    protected void abort() throws IOException {
-        // no-op by default, but subclass such as S3ObjectInputStream may override
-    }
-
-    /**
-     * WARNING: Subclass that overrides this method must NOT call
-     * super.release() or else it would lead to infinite loop.
-     * <p>
-     * {@inheritDoc}
-     */
-    @Override
-    public void release() {
-        // Don't call IOUtils.release(in, null) or else could lead to infinite loop
-        IOUtils.closeQuietly(this, null);
-        InputStream in = getWrappedInputStream();
-        if (in instanceof Releasable) {
-            // This allows any underlying stream that has the close operation
-            // disabled to be truly released
-            Releasable r = (Releasable)in;
-            r.release();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkInternalList.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkInternalList.java
--- ./src/main/java/com/amazonaws/internal/SdkInternalList.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkInternalList.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * List with auto construct flag to indicate whether it is auto constructed by
- * Java SDK.
- */
-public class SdkInternalList<T> extends ArrayList<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-    * Auto construct flag to indicate whether the list is auto constructed by
-    * Java SDK.
-    */
-    private final boolean autoConstruct;
-
-    public SdkInternalList() {
-        super();
-        autoConstruct = true;
-    }
-
-    public SdkInternalList(Collection<? extends T> c) {
-        super(c);
-        autoConstruct = false;
-    }
-
-    public SdkInternalList(int initialCapacity) {
-        super(initialCapacity);
-        autoConstruct = false;
-    }
-
-    /**
-    * Return true if the list is auto constructed by Java SDK
-    */
-    public boolean isAutoConstruct() {
-        return autoConstruct;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkInternalMap.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkInternalMap.java
--- ./src/main/java/com/amazonaws/internal/SdkInternalMap.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkInternalMap.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,135 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Map with auto construct flag to indicate whether it is auto constructed by
- * Java SDK.
- */
-public class SdkInternalMap<K,V> implements Map<K,V>, Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private final Map<K, V> map;
-
-    /**
-    * Auto construct flag to indicate whether the map is auto constructed by
-    * Java SDK.
-    */
-    private final boolean autoConstruct;
-
-    public SdkInternalMap() {
-        this.map = new HashMap<K,V>();
-        autoConstruct = true;
-    }
-
-    public SdkInternalMap(Map<K, V> m) {
-        this.map = m;
-        autoConstruct = false;
-    }
-
-    /**
-    * Return true if the map is auto constructed by Java SDK; false otherwise.
-    */
-    public boolean isAutoConstruct() {
-        return autoConstruct;
-    }
-
-    @Override
-    public int size() {
-        return map.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return map.isEmpty();
-    }
-
-    @Override
-    public boolean containsKey(Object key) {
-        return map.containsKey(key);
-    }
-
-    @Override
-    public boolean containsValue(Object value) {
-        return map.containsValue(value);
-    }
-
-    @Override
-    public V get(Object key) {
-        return map.get(key);
-    }
-
-    @Override
-    public V put(K key, V value) {
-        return map.put(key, value);
-    }
-
-    @Override
-    public V remove(Object key) {
-        return map.remove(key);
-    }
-
-    @Override
-    public void putAll(Map<? extends K, ? extends V> m) {
-        map.putAll(m);
-    }
-
-    @Override
-    public void clear() {
-        map.clear();
-    }
-
-    @Override
-    public Set<K> keySet() {
-        return map.keySet();
-    }
-
-    @Override
-    public Collection<V> values() {
-        return map.values();
-    }
-
-    @Override
-    public Set<Map.Entry<K, V>> entrySet() {
-        return map.entrySet();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (map == null ) return o == null;
-        if (!(o instanceof Map<?,?>)) return false;
-        
-        Map<?, ?> that = (Map<?, ?>) o;
-
-        return map.equals(that);
-    }
-
-    @Override
-    public int hashCode() {
-        return map == null ? 0 : map.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return map == null ? null : map.toString();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkIOUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkIOUtils.java
--- ./src/main/java/com/amazonaws/internal/SdkIOUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkIOUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-import com.amazonaws.log.InternalLogApi;
-import com.amazonaws.log.InternalLogFactory;
-
-/**
- * Utilities for IO operations.
- */
-enum SdkIOUtils {
-    ;
-    private static final InternalLogApi defaultLog = InternalLogFactory.getLog(SdkIOUtils.class);
-
-    static void closeQuietly(Closeable is) {
-        closeQuietly(is, null);
-    }
-    /**
-     * Closes the given Closeable quietly.
-     * @param is the given closeable
-     * @param log logger used to log any failure should the close fail
-     */
-    static void closeQuietly(Closeable is, InternalLogApi log) {
-        if (is != null) {
-            try {
-                is.close();
-            } catch (IOException ex) {
-                InternalLogApi logger = log == null ? defaultLog : log;
-                if (logger.isDebugEnabled())
-                    logger.debug("Ignore failure in closing the Closeable", ex);
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkMetricsSocket.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkMetricsSocket.java
--- ./src/main/java/com/amazonaws/internal/SdkMetricsSocket.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkMetricsSocket.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-
-import com.amazonaws.util.AWSRequestMetrics;
-
-/**
- * A wrapper to Socket with metrics feature to record socket read time.
- */
-public class SdkMetricsSocket extends DelegateSocket {
-
-    private MetricsInputStream metricsIS;
-
-    public SdkMetricsSocket(Socket sock) {
-        super(sock);
-    }
-
-    /**
-     * {@link AWSRequestMetrics} is set per request.
-     */
-    public void setMetrics(AWSRequestMetrics metrics) {
-        if (metricsIS == null) {
-            throw new IllegalStateException(
-                    "The underlying input stream must be initialized!");
-        }
-        metricsIS.setMetrics(metrics);
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        metricsIS = new MetricsInputStream(sock.getInputStream());
-        return metricsIS;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkPredicate.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkPredicate.java
--- ./src/main/java/com/amazonaws/internal/SdkPredicate.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkPredicate.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-/**
- * Similar to Predicate functional interface in Java 8
- */
-public abstract class SdkPredicate<T> {
-
-    /**
-     * Evaluates this predicate on the given argument
-     * 
-     * @param t
-     *            The input argument
-     * @return true if the input argument matches the predicate, otherwise false
-     */
-    public abstract boolean test(T t);
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkSocket.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSocket.java
--- ./src/main/java/com/amazonaws/internal/SdkSocket.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSocket.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,78 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.net.SocketAddress;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class SdkSocket extends DelegateSocket {
-    private static final Log log = LogFactory.getLog(SdkSocket.class);
-
-    public SdkSocket(Socket sock) {
-        super(sock);
-        if (log.isDebugEnabled())
-            log.debug("created: " + endpoint());
-    }
-
-    /**
-     * Returns the endpoint in the format of "address:port"
-     */
-    private String endpoint() {
-        return sock.getInetAddress() + ":" + sock.getPort();
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint) throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("connecting to: " + endpoint);
-        sock.connect(endpoint);
-        if (log.isDebugEnabled())
-            log.debug("connected to: " + endpoint());
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint, int timeout) throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("connecting to: " + endpoint);
-        sock.connect(endpoint, timeout);
-        if (log.isDebugEnabled())
-            log.debug("connected to: " + endpoint());
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("closing " + endpoint());
-        sock.close();
-    }
-
-    @Override
-    public void shutdownInput() throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("shutting down input of " + endpoint());
-        sock.shutdownInput();
-    }
-
-    @Override
-    public void shutdownOutput() throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("shutting down output of " + endpoint());
-        sock.shutdownOutput();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkSSLContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSSLContext.java
--- ./src/main/java/com/amazonaws/internal/SdkSSLContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSSLContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.internal;
-
-import org.apache.http.conn.ssl.SSLContexts;
-import org.apache.http.conn.ssl.SSLInitializationException;
-
-import javax.net.ssl.SSLContext;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-public class SdkSSLContext {
-
-    /**
-     * @see SSLContexts#createDefault()
-     */
-    public static final SSLContext getPreferredSSLContext(final SecureRandom secureRandom) {
-        try {
-            final SSLContext sslcontext = SSLContext.getInstance("TLS");
-            // http://download.java.net/jdk9/docs/technotes/guides/security/jsse/JSSERefGuide.html
-            sslcontext.init(null, null, secureRandom);
-            return sslcontext;
-        } catch (final NoSuchAlgorithmException ex) {
-            throw new SSLInitializationException(ex.getMessage(), ex);
-        } catch (final KeyManagementException ex) {
-            throw new SSLInitializationException(ex.getMessage(), ex);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkSSLMetricsSocket.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSSLMetricsSocket.java
--- ./src/main/java/com/amazonaws/internal/SdkSSLMetricsSocket.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSSLMetricsSocket.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.net.ssl.SSLSocket;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.util.AWSRequestMetrics;
-
-/**
- * A wrapper to SSLSocket with metric feature to record socket read time.
- */
-public class SdkSSLMetricsSocket extends DelegateSSLSocket {
-
-    private MetricsInputStream metricsIS;
-
-    public SdkSSLMetricsSocket(SSLSocket sock) {
-        super(sock);
-    }
-
-    public void setMetrics(AWSRequestMetrics metrics) throws IOException {
-        // make sure metricsIS is initialized.
-        getInputStream();
-        metricsIS.setMetrics(metrics);
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-        if (metricsIS == null) {
-            metricsIS = new MetricsInputStream(sock.getInputStream());
-        }
-        return metricsIS;
-    }
-
-    @SdkTestInternalApi
-    MetricsInputStream getMetricsInputStream() {
-        return metricsIS;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/SdkSSLSocket.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSSLSocket.java
--- ./src/main/java/com/amazonaws/internal/SdkSSLSocket.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/SdkSSLSocket.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,79 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-
-import javax.net.ssl.SSLSocket;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class SdkSSLSocket extends DelegateSSLSocket {
-    private static final Log log = LogFactory.getLog(SdkSSLSocket.class);
-
-    public SdkSSLSocket(SSLSocket sock) {
-        super(sock);
-        if (log.isDebugEnabled())
-            log.debug("created: " + endpoint());
-    }
-
-    /**
-     * Returns the endpoint in the format of "address:port"
-     */
-    private String endpoint() {
-        return sock.getInetAddress() + ":" + sock.getPort();
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint) throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("connecting to: " + endpoint);
-        sock.connect(endpoint);
-        if (log.isDebugEnabled())
-            log.debug("connected to: " + endpoint());
-    }
-
-    @Override
-    public void connect(SocketAddress endpoint, int timeout) throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("connecting to: " + endpoint);
-        sock.connect(endpoint, timeout);
-        if (log.isDebugEnabled())
-            log.debug("connected to: " + endpoint());
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("closing " + endpoint());
-        sock.close();
-    }
-
-    @Override
-    public void shutdownInput() throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("shutting down input of " + endpoint());
-        sock.shutdownInput();
-    }
-
-    @Override
-    public void shutdownOutput() throws IOException {
-        if (log.isDebugEnabled())
-            log.debug("shutting down output of " + endpoint());
-        sock.shutdownOutput();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/internal/ServiceEndpointBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ServiceEndpointBuilder.java
--- ./src/main/java/com/amazonaws/internal/ServiceEndpointBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/internal/ServiceEndpointBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,43 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.internal;
-
-import java.net.URI;
-
-import com.amazonaws.regions.Region;
-
-/**
- * Construct a service endpoint based on metadata like service name and region
- */
-public abstract class ServiceEndpointBuilder {
-
-    /**
-     * Get the URI of the service endpoint
-     * 
-     * @return URI of endpoint
-     */
-    public abstract URI getServiceEndpoint();
-
-    public abstract Region getRegion();
-
-    /**
-     * Changes the region of the endpoint builder
-     * 
-     * @param region
-     *            New region to use in endpoint determination
-     * @return A reference to this updated object so that method calls can be chained together.
-     */
-    public abstract ServiceEndpointBuilder withRegion(Region region);
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/jmx/JmxInfoProviderSupport.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/JmxInfoProviderSupport.java
--- ./src/main/java/com/amazonaws/jmx/JmxInfoProviderSupport.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/JmxInfoProviderSupport.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,85 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.jmx;
-
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadMXBean;
-import java.util.List;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.jmx.spi.JmxInfoProvider;
-
-public class JmxInfoProviderSupport implements JmxInfoProvider {
-    @Override
-    public long[] getFileDecriptorInfo() {
-        MBeanServer mbsc = MBeans.getMBeanServer();
-        AttributeList attributes;
-        try {
-            attributes = mbsc.getAttributes(
-                new ObjectName("java.lang:type=OperatingSystem"), 
-                new String[]{"OpenFileDescriptorCount", "MaxFileDescriptorCount"});
-            List<Attribute> attrList = attributes.asList();
-            long openFdCount = (Long)attrList.get(0).getValue();
-            long maxFdCount = (Long)attrList.get(1).getValue();
-            long[] fdCounts = { openFdCount, maxFdCount};
-            return fdCounts;
-        } catch (Exception e) {
-            LogFactory.getLog(SdkMBeanRegistrySupport.class).debug(
-                    "Failed to retrieve file descriptor info", e);
-        }
-        return null;
-    }
-
-    @Override
-    public int getThreadCount() {
-      ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-      return threadMXBean.getThreadCount();
-    }
-
-    @Override
-    public int getDaemonThreadCount() {
-        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-        return threadMXBean.getDaemonThreadCount();
-    }
-
-    @Override
-    public int getPeakThreadCount() {
-        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-        return threadMXBean.getPeakThreadCount();
-    }
-
-    @Override
-    public long getTotalStartedThreadCount() {
-        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-        return threadMXBean.getTotalStartedThreadCount();
-    }
-
-    @Override
-    public long[] findDeadlockedThreads() {
-        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-        return threadMXBean.findDeadlockedThreads();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/jmx/MBeans.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/MBeans.java
--- ./src/main/java/com/amazonaws/jmx/MBeans.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/MBeans.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,117 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.jmx;
-
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-
-import org.apache.commons.logging.LogFactory;
-
-/**
- * MBean related utilities.
- */
-public enum MBeans {
-    ;
-    /**
-     * Registers the given MBean under the given object name to the first
-     * registered MBean server, or the platform MBean server if there is no
-     * explicitly registered MBean server.
-     * 
-     * @return true if the registration succeeded, or false if an MBean already
-     *         exists under the given object name.
-     * @throws MBeanRegistrationException
-     *             The preRegister (MBeanRegistration interface) method of the
-     *             MBean has thrown an exception. The MBean will not be
-     *             registered.
-     */
-    public static <T> boolean registerMBean(String objectName, T mbean)
-            throws MBeanRegistrationException {
-        MBeanServer server = getMBeanServer();
-        try {
-            server.registerMBean(mbean, new ObjectName(objectName));
-        } catch (MalformedObjectNameException e) {
-            throw new IllegalArgumentException(e);
-        } catch (NotCompliantMBeanException e) {
-            throw new IllegalArgumentException(e);
-        } catch (InstanceAlreadyExistsException e) {
-            LogFactory.getLog(MBeans.class).debug(
-                "Failed to register mbean " + objectName, e);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Unregisters the MBean under the given object name to the first MBean
-     * server, or the platform MBean server if there is no explicitly registered
-     * MBean server.
-     * 
-     * @return true if the unregistration succeeded, or false if the MBean
-     *         doesn't exist under the given object name.
-     * @throws MBeanRegistrationException
-     *             Wraps exceptions thrown by the preRegister(), preDeregister()
-     *             methods of the MBeanRegistration interface.
-     */
-    public static <T> boolean unregisterMBean(String objectName)
-            throws MBeanRegistrationException {
-        MBeanServer server = getMBeanServer();
-        try {
-            server.unregisterMBean(new ObjectName(objectName));
-        } catch (MalformedObjectNameException e) {
-            throw new IllegalArgumentException(e);
-        } catch (InstanceNotFoundException e) {
-            LogFactory.getLog(MBeans.class).debug(
-                    "Failed to unregister mbean " + objectName, e);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns true if an MBean identified by the specified object name is
-     * already registered with the first MBean server, or the platform MBean
-     * server if there is no explicitly registered MBean server; false
-     * otherwise.
-     */
-    public static boolean isRegistered(String objectName) {
-        MBeanServer server = getMBeanServer();
-        try {
-            return server.isRegistered(new ObjectName(objectName));
-        } catch (MalformedObjectNameException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    /**
-     * Returns the first registered MBean server, or the platform MBean server
-     * if there is none.
-     */
-    public static MBeanServer getMBeanServer() {
-        List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
-        MBeanServer server = servers.size() > 0
-            ? servers.get(0)
-            : ManagementFactory.getPlatformMBeanServer();
-        return server;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/jmx/SdkMBeanRegistrySupport.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/SdkMBeanRegistrySupport.java
--- ./src/main/java/com/amazonaws/jmx/SdkMBeanRegistrySupport.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/SdkMBeanRegistrySupport.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,48 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.jmx;
-
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.jmx.spi.SdkMBeanRegistry;
-import com.amazonaws.metrics.MetricAdmin;
-
-public class SdkMBeanRegistrySupport implements SdkMBeanRegistry {
-    ;
-    @Override
-    public boolean registerMetricAdminMBean(String objectName) {
-        try {
-            return MBeans.registerMBean(objectName, new MetricAdmin());
-        } catch(Exception ex) {
-            LogFactory.getLog(SdkMBeanRegistrySupport.class).warn("", ex);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean unregisterMBean(String objectName) {
-        try {
-            return MBeans.unregisterMBean(objectName);
-        } catch(Exception ex) {
-            LogFactory.getLog(SdkMBeanRegistrySupport.class).warn("", ex);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isMBeanRegistered(String objectName) {
-        return MBeans.isRegistered(objectName);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/jmx/spi/JmxInfoProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/spi/JmxInfoProvider.java
--- ./src/main/java/com/amazonaws/jmx/spi/JmxInfoProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/spi/JmxInfoProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,87 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.jmx.spi;
-
-import org.apache.commons.logging.LogFactory;
-
-/**
- * SPI used to retrieve JMX information and can survive the absence of JMX.
- */
-public interface JmxInfoProvider {
-    public long[] getFileDecriptorInfo();
-    public int getThreadCount();
-    public int getDaemonThreadCount();
-    public int getPeakThreadCount();
-    public long getTotalStartedThreadCount();
-    public long[] findDeadlockedThreads();
-    public boolean isEnabled();
-
-    public static class Factory {
-        private static final JmxInfoProvider provider;
-        static {
-            JmxInfoProvider p;
-            try {
-                Class<?> c = Class.forName("com.amazonaws.jmx.JmxInfoProviderSupport");
-                p = (JmxInfoProvider)c.newInstance();
-            } catch (Exception e) {
-                LogFactory
-                    .getLog(JmxInfoProvider.class)
-                    .debug("Failed to load the JMX implementation module - JMX is disabled", e);
-                p = NONE;
-            }
-            provider = p;
-        }
-        public static JmxInfoProvider getJmxInfoProvider() {
-            return provider;
-        }
-    }
-
-    static final JmxInfoProvider NONE = new JmxInfoProvider() {
-        @Override
-        public long[] getFileDecriptorInfo() {
-            return null;
-        }
-
-        @Override
-        public int getThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public int getDaemonThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public int getPeakThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public long getTotalStartedThreadCount() {
-            return 0;
-        }
-
-        @Override
-        public long[] findDeadlockedThreads() {
-            return null;
-        }
-
-        @Override
-        public boolean isEnabled() {
-            return false;
-        }
-    };
-}
diff -Nau8r ./src/main/java/com/amazonaws/jmx/spi/SdkMBeanRegistry.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/spi/SdkMBeanRegistry.java
--- ./src/main/java/com/amazonaws/jmx/spi/SdkMBeanRegistry.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/jmx/spi/SdkMBeanRegistry.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,72 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.jmx.spi;
-
-import org.apache.commons.logging.LogFactory;
-
-/**
- * SPI used to register MBeans and can survive the absence of JMX.
- */
-public interface SdkMBeanRegistry {
-    /**
-     * Returns true if the registration of the admin MBean under the given
-     * object name succeeded; false otherwise.
-     */
-    public boolean registerMetricAdminMBean(String objectName);
-
-    /**
-     * Returns true if the unregistration of the MBean under the given object
-     * name succeeded; false otherwise.
-     */
-    public boolean unregisterMBean(String objectName);
-
-    /**
-     * Returns true if the the MBean under the given object name is currently
-     * registered; false otherwise.
-     */
-    public boolean isMBeanRegistered(String objectName);
-
-    public static class Factory {
-        private static final SdkMBeanRegistry registry;
-        static {
-            SdkMBeanRegistry rego;
-            try {
-                Class<?> c = Class.forName("com.amazonaws.jmx.SdkMBeanRegistrySupport");
-                rego = (SdkMBeanRegistry)c.newInstance();
-            } catch (Exception e) {
-                LogFactory
-                    .getLog(SdkMBeanRegistry.class)
-                    .debug("Failed to load the JMX implementation module - JMX is disabled", e);
-                rego = NONE;
-            }
-            registry = rego;
-        }
-        public static SdkMBeanRegistry getMBeanRegistry() {
-            return registry;
-        }
-    }
-    
-    static final SdkMBeanRegistry NONE = new SdkMBeanRegistry() {
-        @Override public boolean registerMetricAdminMBean(String objectName) {
-            return false;
-        }
-        @Override public boolean unregisterMBean(String objectName) {
-            return false;
-        }
-        @Override public boolean isMBeanRegistered(String objectName) {
-            return false;
-        }
-    };
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/AwsSdkMetrics.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/AwsSdkMetrics.java
--- ./src/main/java/com/amazonaws/metrics/AwsSdkMetrics.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/AwsSdkMetrics.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,962 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.metrics;
-import static com.amazonaws.SDKGlobalConfiguration.DEFAULT_METRICS_SYSTEM_PROPERTY;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import com.amazonaws.regions.Region;
-import com.amazonaws.regions.RegionUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.SDKGlobalConfiguration;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
-import com.amazonaws.auth.PropertiesCredentials;
-import com.amazonaws.jmx.spi.SdkMBeanRegistry;
-import com.amazonaws.regions.Regions;
-import com.amazonaws.util.AWSRequestMetrics;
-import com.amazonaws.util.AWSRequestMetrics.Field;
-import com.amazonaws.util.AWSServiceMetrics;
-
-/**
- * Used to control the default AWS SDK metric collection system.
- * <p>
- * The default metric collection of the Java AWS SDK is disabled by default. To
- * enable it, simply specify the system property
- * <b>"com.amazonaws.sdk.enableDefaultMetrics"</b> when starting up the JVM.
- * When the system property is specified, a default metric collector will be
- * started at the AWS SDK level. The default implementation uploads the
- * request/response metrics captured to Amazon CloudWatch using AWS credentials
- * obtained via the {@link DefaultAWSCredentialsProviderChain}.
- * <p>
- * By default, the metrics are uploaded to the us-east-1 region. You can
- * change the region by changing the system property as
- * -Dcom.amazonaws.sdk.enableDefaultMetrics=cloudwatchRegion={newregion}
- * See #CLOUDWATCH_REGION
- * </p>
- * <p>
- * For additional optional attributes that can be specified for the system
- * property, please read the javadoc of the individual fields of
- * this class for more details.
- * <p>
- * Instead of via system properties, the default AWS SDK metric collection can
- * also be enabled programmatically via {@link #enableDefaultMetrics()}.
- * Similarly, metric collection at the AWS SDK level can be disabled via
- * {@link #disableMetrics()}.
- * <p>
- * Clients who needs to fully customize the metric collection can implement the
- * SPI {@link MetricCollector}, and then replace the default AWS SDK
- * implementation of the collector via
- * {@link #setMetricCollector(MetricCollector)}.
- * <p>
- * Alternatively, for limited customization of the internal collector
- * implementation provided by the AWS SDK, one can extend the internal Amazon
- * CloudWatch metric collector. See the javadoc at
- * com.amazonaws.metrics.internal.cloudwatch.CloudWatchMetricConfig for more
- * details.
- */
-public enum AwsSdkMetrics {
-    ;
-    private static final Log log = LogFactory.getLog(AwsSdkMetrics.class);
-    public static final String DEFAULT_METRIC_NAMESPACE = "AWSSDK/Java";
-    private static final String MBEAN_OBJECT_NAME =
-        "com.amazonaws.management:type=" + AwsSdkMetrics.class.getSimpleName();
-
-    /**
-     * Object name under which the Admin Mbean of the current classloader is
-     * registered.
-     */
-    private static volatile String registeredAdminMbeanName;
-    /**
-     * Used to enable the use of a single metric namespace for all levels of SDK
-     * generated CloudWatch metrics such as JVM level, host level, etc.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=useSingleMetricNamespace
-     * </pre>
-     */
-    public static final String USE_SINGLE_METRIC_NAMESPACE = "useSingleMetricNamespace";
-    /**
-     * Used to exclude the generation of JVM metrics when the AWS SDK default
-     * metrics is enabled.
-     * By default, jvm metrics is included.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=excludeJvmMetrics
-     * </pre>
-     */
-    public static final String EXCLUDE_MACHINE_METRICS = "excludeMachineMetrics";
-
-    /**
-     * Used to generate per host level metrics when the AWS SDK default
-     * metrics is enabled.
-     * By default, per-host level metrics is excluded.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=includePerHostMetrics
-     * </pre>
-     */
-    public static final String INCLUDE_PER_HOST_METRICS = "includePerHostMetrics";
-
-    /**
-     * Used to specify an AWS credential property file.
-     * By default, the {@link DefaultAWSCredentialsProviderChain} is used.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=credentialFile=/path/aws.properties
-     * </pre>
-     * @deprecated in favor of {@link AWS_CREDENTIAL_PROPERTIES_FILE}
-     */
-    public static final String AWS_CREDENTAIL_PROPERTIES_FILE= "credentialFile";
-
-    /**
-     * Used to specify an AWS credential property file.
-     * By default, the {@link DefaultAWSCredentialsProviderChain} is used.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=credentialFile=/path/aws.properties
-     * </pre>
-     */
-    public static final String AWS_CREDENTIAL_PROPERTIES_FILE= "credentialFile";
-
-    /**
-     * Used to specify the Amazon CloudWatch region for metrics uploading purposes.
-     * By default, metrics are uploaded to us-east-1.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=cloudwatchRegion=us-west-2
-     * </pre>
-     */
-    public static final String CLOUDWATCH_REGION = "cloudwatchRegion";
-
-    /**
-     * Used to specify the internal in-memory queue size for queuing metrics
-     * data points. The default size is 1,000.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=metricQueueSize=1000
-     * </pre>
-     */
-    public static final String METRIC_QUEUE_SIZE = "metricQueueSize";
-
-    /**
-     * Used to specify the internal queue polling timeout in millisecond.
-     * The default timeout is 1 minute, which is optimal for the default
-     * CloudWatch implementation.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=getQueuePollTimeoutMilli=60000
-     * </pre>
-     */
-    public static final String QUEUE_POLL_TIMEOUT_MILLI = "getQueuePollTimeoutMilli";
-
-    /**
-     * Used to specify a custom metric name space.
-     * The default name space is {@link #DEFAULT_METRIC_NAMESPACE}.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=metricNameSpace=MyNameSpace
-     * </pre>
-     */
-    public static final String METRIC_NAME_SPACE = "metricNameSpace";
-
-    /**
-     * Used to generate per JVM level metrics when the AWS SDK default
-     * metrics is enabled.
-     * By default, JVM level metrics are not generated.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=jvmMetricName=Tomcat1
-     * </pre>
-     */
-    public static final String JVM_METRIC_NAME = "jvmMetricName";
-
-    /**
-     * Used to explicitly specify the host name for metric purposes, instead of
-     * detecting the host name via {@link InetAddress} when the AWS SDK default
-     * metrics is enabled. Specifying the host name also has the side effecting
-     * of enabling per host level metrics.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=hostMetricName=MyHost
-     * </pre>
-     */
-    public static final String HOST_METRIC_NAME = "hostMetricName";
-
-    private static final String DEFAULT_METRIC_COLLECTOR_FACTORY =
-        "com.amazonaws.metrics.internal.cloudwatch.DefaultMetricCollectorFactory";
-
-    /**
-     * Used to explicitly enable {@link Field#HttpSocketReadTime} for recording socket read time.
-     *
-     * <pre>
-     * Example:
-     *  -Dcom.amazonaws.sdk.enableDefaultMetrics=enableHttpSocketReadMetric
-     * </pre>
-     */
-    private static final String ENABLE_HTTP_SOCKET_READ_METRIC = "enableHttpSocketReadMetric";
-    /**
-     * True if the system property {@link #DEFAULT_METRICS_SYSTEM_PROPERTY} has
-     * been set; false otherwise.
-     */
-    private static final boolean defaultMetricsEnabled;
-    private static volatile AWSCredentialsProvider credentialProvider;
-    /**
-     * True if machine metrics is to be excluded; false otherwise.
-     */
-    private static volatile boolean machineMetricsExcluded;
-    /**
-     * True if per-host metrics is to be included; false if per-host metrics is
-     * to be excluded when {@link #hostMetricName} is not specified. In the
-     * absence of {@link #hostMetricName}, the host name will be automatically
-     * detected via {@link InetAddress}.
-     */
-    private static volatile boolean perHostMetricsIncluded;
-
-    /**
-     * True if socket read time metric is enabled; false otherwise. The {@link Field#HttpSocketReadTime}
-     * could have a big impact to performance, disabled by default.
-     */
-    private static volatile boolean httpSocketReadMetricEnabled;
-
-    private static volatile Region region;
-    private static volatile Integer metricQueueSize;
-    private static volatile Long queuePollTimeoutMilli;
-    private static volatile String metricNameSpace = DEFAULT_METRIC_NAMESPACE;
-    private static volatile String credentialFile;
-
-    /**
-     * No JVM level metrics is generated if this field is set to null or blank.
-     * Otherwise, the value in this field is used to compose the metric name
-     * space.
-     *
-     * Example:
-     * <ol>
-     * <li>If jvmMetricName="Tomcat1" and host-level metrics is disabled, the
-     * metric name space will be something like: "AWSSDK/Java/Tomcat1".</li>
-     * <li>If jvmMetricName="Tomcat1" and host-level metrics is enabled, the
-     * metric name space will be something like:
-     * "AWSSDK/Java/myhost.mycompany.com/Tomcat1".</li>
-     * <li>If jvmMetricName="Tomcat1" and host-level metrics is enabled and the
-     * metricNameSpace="MyNameSpace", the metric name space will be something
-     * like: "MyNameSpace/myhost.mycompany.com/Tomcat1".</li>
-     * </ol>
-     */
-    private static volatile String jvmMetricName;
-    private static volatile String hostMetricName;
-    /**
-     * True if the same metric namespace is to be used for all levels (such as
-     * JVM level, host-level, etc.) of AWS Cloudwatch Metrics for the Java SDK;
-     * false otherwise.
-     */
-    private static volatile boolean singleMetricNamespace;
-
-    static {
-        String defaultMetrics = System.getProperty(DEFAULT_METRICS_SYSTEM_PROPERTY);
-        defaultMetricsEnabled = defaultMetrics != null;
-        if (defaultMetricsEnabled) {
-            String[] values = defaultMetrics.split(",");
-            boolean excludeMachineMetrics = false;
-            boolean includePerHostMetrics = false;
-            boolean useSingleMetricNamespace = false;
-            boolean enableHttpSocketReadMetric = false;
-            for (String s: values) {
-                String part = s.trim();
-                if (!excludeMachineMetrics && EXCLUDE_MACHINE_METRICS.equals(part)) {
-                    excludeMachineMetrics = true;
-                } else if (!includePerHostMetrics && INCLUDE_PER_HOST_METRICS.equals(part)) {
-                    includePerHostMetrics = true;
-                } else if (!useSingleMetricNamespace && USE_SINGLE_METRIC_NAMESPACE.equals(part)) {
-                    useSingleMetricNamespace = true;
-                } else if (!enableHttpSocketReadMetric && ENABLE_HTTP_SOCKET_READ_METRIC.equals(part)) {
-                    enableHttpSocketReadMetric = true;
-                } else {
-                    String[] pair = part.split("=");
-                    if (pair.length == 2) {
-                        String key = pair[0].trim();
-                        String value  = pair[1].trim();
-                        try {
-                            if (AWS_CREDENTAIL_PROPERTIES_FILE.equals(key)
-                                    || AWS_CREDENTIAL_PROPERTIES_FILE.equals(key)) {
-                                setCredentialFile0(value);
-                            } else if (CLOUDWATCH_REGION.equals(key)) {
-                                region = RegionUtils.getRegion(value);
-                            } else if (METRIC_QUEUE_SIZE.equals(key)) {
-                            	Integer i = Integer.valueOf(value);
-                                if (i.intValue() < 1)
-                                    throw new IllegalArgumentException(METRIC_QUEUE_SIZE + " must be at least 1");
-                                metricQueueSize = i;
-                            } else if (QUEUE_POLL_TIMEOUT_MILLI.equals(key)) {
-                            	Long i = Long.valueOf(value);
-                                if (i.intValue() < 1000)
-                                    throw new IllegalArgumentException(QUEUE_POLL_TIMEOUT_MILLI + " must be at least 1000");
-                                queuePollTimeoutMilli = i;
-                            } else if (METRIC_NAME_SPACE.equals(key)) {
-                                metricNameSpace = value;
-                            } else if (JVM_METRIC_NAME.equals(key)) {
-                                jvmMetricName = value;
-                            } else if (HOST_METRIC_NAME.equals(key)) {
-                                hostMetricName = value;
-                            } else {
-                                LogFactory.getLog(AwsSdkMetrics.class).debug("Ignoring unrecognized parameter: " + part);
-                            }
-                        } catch (Exception e) {
-                            LogFactory.getLog(AwsSdkMetrics.class).debug("Ignoring failure", e);
-                        }
-                    }
-                }
-            }
-            machineMetricsExcluded = excludeMachineMetrics;
-            perHostMetricsIncluded = includePerHostMetrics;
-            singleMetricNamespace = useSingleMetricNamespace;
-            httpSocketReadMetricEnabled = enableHttpSocketReadMetric;
-        }
-    }
-
-    private static final MetricRegistry registry = new MetricRegistry();
-    private static volatile MetricCollector mc;
-    /**
-     * Used to disallow re-entrancy in enabling the default metric collection system.
-     */
-    private static boolean dirtyEnabling;
-    /** Exports AwsSdkMetrics for JMX access. */
-    static {
-        try {
-            registerMetricAdminMBean();
-        } catch(Exception ex) {
-            LogFactory.getLog(AwsSdkMetrics.class).warn("", ex);
-        }
-    }
-
-    /**
-     * Returns true if the metric admin MBean is currently registered for JMX
-     * access; false otherwise.
-     */
-    public static boolean isMetricAdminMBeanRegistered() {
-        SdkMBeanRegistry registry = SdkMBeanRegistry.Factory.getMBeanRegistry();
-        return registeredAdminMbeanName != null
-                && registry.isMBeanRegistered(registeredAdminMbeanName);
-    }
-
-    /**
-     * Returns the name of the registered admin mbean; or null if the admin
-     * mbean is not currently registered.
-     */
-    public static String getRegisteredAdminMbeanName() {
-        return registeredAdminMbeanName;
-    }
-
-    /**
-     * Registers the metric admin MBean for JMX access for the current
-     * classloader. If an AdminMbean is found to have been registered under a
-     * different class loader, the AdminMBean of the current class loader would
-     * be registered under the same name {@link #MBEAN_OBJECT_NAME} but with an
-     * additional suffix in the format of "/<count>", where count is a counter
-     * incrementing from 1.
-     *
-     * @return true if the registeration succeeded; false otherwise.
-     */
-    public static boolean registerMetricAdminMBean() {
-        SdkMBeanRegistry registry = SdkMBeanRegistry.Factory.getMBeanRegistry();
-        synchronized(AwsSdkMetrics.class) {
-            if (registeredAdminMbeanName != null)
-                return false;   // already registered
-            boolean registered = registry.registerMetricAdminMBean(MBEAN_OBJECT_NAME);
-            if (registered) {
-                registeredAdminMbeanName = MBEAN_OBJECT_NAME;
-            } else {
-                String mbeanName = MBEAN_OBJECT_NAME;
-                int count = 0;
-                while (registry.isMBeanRegistered(mbeanName)) {
-                    mbeanName = MBEAN_OBJECT_NAME + "/" + ++count;
-                }
-                registered = registry.registerMetricAdminMBean(mbeanName);
-                if (registered)
-                    registeredAdminMbeanName = mbeanName;
-            }
-            if (registered)
-                log.debug("Admin mbean registered under " + registeredAdminMbeanName);
-            return registered;
-        }
-    }
-
-    /**
-     * Unregisters the metric admin MBean from JMX for the current classloader.
-     *
-     * @return true if the unregistration succeeded or if there is no admin
-     *         MBean registered; false otherwise.
-     */
-    public static boolean unregisterMetricAdminMBean() {
-        SdkMBeanRegistry registry = SdkMBeanRegistry.Factory.getMBeanRegistry();
-        synchronized(AwsSdkMetrics.class) {
-            if (registeredAdminMbeanName == null)
-                return true;
-            boolean success = registry.unregisterMBean(registeredAdminMbeanName);
-            if (success)
-                registeredAdminMbeanName = null;
-            return success;
-        }
-    }
-    /**
-     * Returns a non-null request metric collector for the SDK. If no custom
-     * request metric collector has previously been specified via
-     * {@link #setMetricCollector(MetricCollector)} and the
-     * {@link SDKGlobalConfiguration#DEFAULT_METRICS_SYSTEM_PROPERTY} has been set, then this method
-     * will initialize and return the default metric collector provided by the
-     * AWS SDK on a best-attempt basis.
-     */
-    public static <T extends RequestMetricCollector> T getRequestMetricCollector() {
-        if (mc == null) {
-            if (isDefaultMetricsEnabled())
-                enableDefaultMetrics();
-        }
-        @SuppressWarnings("unchecked")
-        T t = (T)(mc == null ? RequestMetricCollector.NONE : mc.getRequestMetricCollector());
-        return t;
-    }
-
-    public static <T extends ServiceMetricCollector> T getServiceMetricCollector() {
-        if (mc == null) {
-            if (isDefaultMetricsEnabled())
-                enableDefaultMetrics();
-        }
-        @SuppressWarnings("unchecked")
-        T t = (T)(mc == null ? ServiceMetricCollector.NONE : mc.getServiceMetricCollector());
-        return t;
-    }
-
-    /**
-     * This method should never be called by anyone except the JMX MBean used
-     * for administrative purposes only.
-     */
-    static MetricCollector getInternalMetricCollector() {
-        return mc;
-    }
-
-    public static <T extends MetricCollector> T getMetricCollector() {
-        if (mc == null) {
-            if (isDefaultMetricsEnabled())
-                enableDefaultMetrics();
-        }
-        @SuppressWarnings("unchecked")
-        T t = (T)(mc == null ? MetricCollector.NONE : mc);
-        return t;
-    }
-
-    /**
-     * Sets the metric collector to be used by the AWS SDK, and stop the
-     * previously running collector used by the AWS SDK, if any. Note, however,
-     * a request metric collector specified at the web service client level or
-     * request level, if any, always takes precedence over the one specified at
-     * the AWS SDK level.
-     * <p>
-     * Caller of this method is responsible for starting the new metric
-     * collector specified as the input parameter.
-     *
-     * @param mc
-     *            the metric collector to be used by the AWS SDK; or
-     *            null if no metric collection is to be performed
-     *            at the AWS SDK level.
-     *
-     * @see RequestMetricCollector
-     * @see RequestMetricCollector#NONE
-     */
-    public static synchronized void setMetricCollector(MetricCollector mc) {
-        MetricCollector old = AwsSdkMetrics.mc;
-        AwsSdkMetrics.mc = mc;
-        if (old != null) {
-            old.stop();
-        }
-    }
-
-    /**
-     * Used to set whether the machine metrics is to be excluded.
-     *
-     * @param excludeMachineMetrics true if machine metrics is to be excluded;
-     * false otherwise.
-     */
-    public static void setMachineMetricsExcluded(boolean excludeMachineMetrics) {
-        AwsSdkMetrics.machineMetricsExcluded = excludeMachineMetrics;
-    }
-
-    /**
-     * Used to set whether the per-host metrics is to be included.
-     *
-     * @param includePerHostMetrics true if per-host metrics is to be included;
-     * false otherwise.
-     */
-    public static void setPerHostMetricsIncluded(boolean includePerHostMetrics) {
-        AwsSdkMetrics.perHostMetricsIncluded = includePerHostMetrics;
-    }
-
-    /**
-     * Used to enable {@link Field#HttpSocketReadTime} metric since by default it is disabled.
-     */
-    public static void enableHttpSocketReadMetric() {
-        AwsSdkMetrics.httpSocketReadMetricEnabled = true;
-    }
-
-    /**
-     * Returns true if the system property
-     * {@link SDKGlobalConfiguration#DEFAULT_METRICS_SYSTEM_PROPERTY} has been
-     * set; false otherwise.
-     */
-    public static boolean isDefaultMetricsEnabled() {
-        return defaultMetricsEnabled;
-    }
-
-    /**
-     * Returns true if a single metric name space is to be used for all
-     * levels of SDK generated CloudWatch metrics, including JVM level, host
-     * level, etc.; false otherwise.
-     */
-    public static boolean isSingleMetricNamespace() {
-        return singleMetricNamespace;
-    }
-
-    /**
-     * Used to set whether a single metric name space is to be used for all
-     * levels of SDK generated CloudWatch metrics, including JVM level, host
-     * level, etc.
-     *
-     * @param singleMetricNamespace
-     *            true if single metric name is to be used; false otherwise.
-     */
-    public static void setSingleMetricNamespace(boolean singleMetricNamespace) {
-        AwsSdkMetrics.singleMetricNamespace = singleMetricNamespace;
-    }
-
-    /**
-     * Returns true if metrics at the AWS SDK level is enabled; false
-     * if disabled.
-     */
-    public static boolean isMetricsEnabled() {
-        MetricCollector mc = AwsSdkMetrics.mc;
-        return mc != null && mc.isEnabled();
-    }
-
-    /**
-     * Returns true if machine metrics is to be excluded.
-     */
-    public static boolean isMachineMetricExcluded() {
-        return machineMetricsExcluded;
-    }
-
-    /**
-     * Returns true if the per-host metrics flag has been set; false otherwise.
-     */
-    public static boolean isPerHostMetricIncluded() {
-        return perHostMetricsIncluded;
-    }
-
-    /**
-     * Returns true if per-host metrics is enabled; false otherwise.
-     */
-    public static boolean isPerHostMetricEnabled() {
-        if (perHostMetricsIncluded)
-            return true;
-        String host = hostMetricName;
-        host = host == null ? "" : host.trim();
-        return host.length() > 0;
-    }
-
-    /**
-     * Returns true if HttpSocketReadMetric is enabled; false otherwise.
-     */
-    public static boolean isHttpSocketReadMetricEnabled() {
-        return httpSocketReadMetricEnabled;
-    }
-
-    /**
-     * Starts the default AWS SDK metric collector, but
-     * only if no metric collector is currently in use at the AWS SDK
-     * level.
-     *
-     * @return true if the default AWS SDK metric collector has been
-     *         successfully started by this call; false otherwise.
-     */
-    public static synchronized boolean enableDefaultMetrics() {
-        if (mc == null || !mc.isEnabled()) {
-            if (dirtyEnabling) {
-                throw new IllegalStateException("Reentrancy is not allowed");
-            }
-            dirtyEnabling = true;
-            try {
-                Class<?> c = Class.forName(DEFAULT_METRIC_COLLECTOR_FACTORY);
-                MetricCollector.Factory f = (MetricCollector.Factory)c.newInstance();
-                MetricCollector instance = f.getInstance();
-                if (instance != null) {
-                    setMetricCollector(instance);
-                    return true;
-                }
-            } catch (Exception e) {
-                LogFactory.getLog(AwsSdkMetrics.class)
-                    .warn("Failed to enable the default metrics", e);
-            } finally {
-                dirtyEnabling = false;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Convenient method to disable the metric collector at the AWS SDK
-     * level.
-     */
-    public static void disableMetrics() {
-        setMetricCollector(MetricCollector.NONE);
-    }
-
-    /**
-     * Adds the given metric type to the registry of predefined metrics to be
-     * captured at the AWS SDK level.
-     *
-     * @return true if the set of predefined metric types gets changed as a
-     *        result of the call
-     */
-    public static boolean add(MetricType type) {
-        return type == null ? false : registry.addMetricType(type);
-    }
-    /**
-     * Adds the given metric types to the registry of predefined metrics to be
-     * captured at the AWS SDK level.
-     *
-     * @return true if the set of predefined metric types gets changed as a
-     *        result of the call
-     */
-    public static <T extends MetricType> boolean addAll(Collection<T> types) {
-        return types == null || types.size() == 0
-             ? false
-             : registry.addMetricTypes(types);
-    }
-    /**
-     * Sets the given metric types to replace the registry of predefined metrics
-     * to be captured at the AWS SDK level.
-     */
-    public static <T extends MetricType> void set(Collection<T> types) {
-        registry.setMetricTypes(types);
-    }
-    /**
-     * Removes the given metric type from the registry of predefined metrics to
-     * be captured at the AWS SDK level.
-     *
-     * @return true if the set of predefined metric types gets changed as a
-     *        result of the call
-     */
-    public static boolean remove(MetricType type) {
-        return type == null ? false : registry.removeMetricType(type);
-    }
-    /**
-     * Returns an unmodifiable set of the current predefined metrics.
-     */
-    public static Set<MetricType> getPredefinedMetrics() {
-        return registry.predefinedMetrics();
-    }
-
-    /**
-     * Returns the credential provider for the default AWS SDK metric implementation.
-     * This method is restricted to calls from the default AWS SDK metric implementation.
-     *
-     * @throws SecurityException if called outside the default AWS SDK metric implementation.
-     */
-    public static AWSCredentialsProvider getCredentialProvider() {
-        StackTraceElement[] e = Thread.currentThread().getStackTrace();
-        for (int i=0; i < e.length; i++) {
-            if (e[i].getClassName().equals(DEFAULT_METRIC_COLLECTOR_FACTORY)) {
-                return credentialProvider;
-            }
-        }
-        SecurityException ex = new SecurityException();
-        LogFactory.getLog(AwsSdkMetrics.class).warn("Illegal attempt to access the credential provider", ex);
-        throw ex;
-    }
-
-    /**
-     * Sets the credential provider for the default AWS SDK metric
-     * implementation; or null if the default is to be used. Calling this method
-     * may result in the credential provider being different from the credential
-     * file property.
-     */
-    public static synchronized void setCredentialProvider(
-            AWSCredentialsProvider provider) {
-        credentialProvider = provider;
-    }
-
-    /**
-     * Returns the region configured for the default AWS SDK metric collector;
-     * or null if the default is to be used.
-     *
-     * @throws IllegalArgumentException when using a region not included in
-     * {@link Regions}
-     *
-     * @deprecated Use {@link #getRegionName()}
-     */
-    public static Regions getRegion() throws IllegalArgumentException {
-        return Regions.fromName(region.getName());
-    }
-
-    /**
-     * Returns the region name configured for the default AWS SDK metric collector;
-     * or null if the default is to be used.
-     */
-    public static String getRegionName() {
-        return region == null ? null : region.getName();
-    }
-
-    /**
-     * Sets the region to be used for the default AWS SDK metric collector;
-     * or null if the default is to be used.
-     */
-    public static void setRegion(Regions region) {
-        AwsSdkMetrics.region = RegionUtils.getRegion(region.getName());
-    }
-
-    /**
-     * Sets the region to be used for the default AWS SDK metric collector;
-     * or null if the default is to be used.
-     */
-    public static void setRegion(String region) {
-        AwsSdkMetrics.region = RegionUtils.getRegion(region);
-    }
-
-    /**
-     * Returns the last set AWS credential file, or null if there is none.
-     */
-    public static String getCredentailFile() {
-        return credentialFile;
-    }
-
-    /**
-     * Sets the AWS credential file to be used for accessing Amazon CloudWatch.
-     * Successfully calling this method would result in the AWS credential
-     * provider to make use of the given credential file.
-     */
-    public static void setCredentialFile(String filepath)
-            throws FileNotFoundException, IOException {
-        setCredentialFile0(filepath);
-    }
-
-    /**
-     * Internal method to implement the {@link #setCredentialFile(String)}.
-     */
-    private static void setCredentialFile0(String filepath)
-            throws FileNotFoundException, IOException {
-        final PropertiesCredentials cred =
-            new PropertiesCredentials(new File(filepath));
-        synchronized(AwsSdkMetrics.class) {
-            credentialProvider = new AWSCredentialsProvider() {
-                @Override public void refresh() {}
-                @Override public AWSCredentials getCredentials() {
-                    return cred;
-                }
-            };
-            AwsSdkMetrics.credentialFile = filepath;
-        }
-    }
-
-    /**
-     * Returns the internal metric queue size to be used for the default AWS SDK
-     * metric collector; or null if the default is to be used.
-     */
-    public static Integer getMetricQueueSize() {
-        return metricQueueSize;
-    }
-
-    /**
-     * Sets the metric queue size to be used for the default AWS SDK metric collector;
-     * or null if the default is to be used.
-     */
-    public static void setMetricQueueSize(Integer size) {
-        metricQueueSize = size;
-    }
-
-    /**
-     * Returns the internal metric queue timeout in millisecond to be used for
-     * the default AWS SDK metric collector; or null if the default is to be
-     * used.
-     */
-    public static Long getQueuePollTimeoutMilli() {
-        return queuePollTimeoutMilli;
-    }
-
-    /**
-     * Sets the queue poll time in millisecond to be used for the default AWS
-     * SDK metric collector; or null if the default is to be used.
-     */
-    public static void setQueuePollTimeoutMilli(Long timeoutMilli) {
-        queuePollTimeoutMilli = timeoutMilli;
-    }
-
-    /**
-     * Returns the metric name space, which is never null or blank.
-     */
-    public static String getMetricNameSpace() {
-        return metricNameSpace;
-    }
-
-    /**
-     * Sets the metric name space.
-     *
-     * @param metricNameSpace
-     *            metric name space which must neither be null or blank.
-     *
-     * @throws IllegalArgumentException
-     *             if the specified metric name space is either null or blank.
-     */
-    public static void setMetricNameSpace(String metricNameSpace) {
-        if (metricNameSpace == null || metricNameSpace.trim().length() == 0)
-            throw new IllegalArgumentException();
-        AwsSdkMetrics.metricNameSpace = metricNameSpace;
-    }
-
-    /**
-     * Returns the name of the JVM for generating per-JVM level metrics;
-     * or null or blank if per-JVM level metrics are disabled.
-     */
-    public static String getJvmMetricName() {
-        return jvmMetricName;
-    }
-
-    /**
-     * Sets the name of the JVM for generating per-JVM level metrics.
-     *
-     * @param jvmMetricName
-     *            name of the JVM for generating per-JVM level metrics; or null
-     *            or blank if per-JVM level metrics are to be disabled.
-     */
-    public static void setJvmMetricName(String jvmMetricName) {
-        AwsSdkMetrics.jvmMetricName = jvmMetricName;
-    }
-
-    /**
-     * Returns the host name for generating per-host level metrics; or
-     * null or blank if the host is to be automatically detected via
-     * {@link InetAddress}.
-     */
-    public static String getHostMetricName() {
-        return hostMetricName;
-    }
-
-    /**
-     * Sets the host name for generating per-host level metrics.
-     *
-     * @param hostMetricName
-     *            host name for generating per-host level metrics; or
-     *            null or blank if the host is to be automatically detected via
-     *            {@link InetAddress}.
-     */
-    public static void setHostMetricName(String hostMetricName) {
-        AwsSdkMetrics.hostMetricName = hostMetricName;
-    }
-
-    /**
-     * Used as a registry for the predefined metrics to be captured by the
-     * metric collector at the AWS SDK level.
-     */
-    private static class MetricRegistry {
-        private final Set<MetricType> metricTypes = new HashSet<MetricType>();
-        private volatile Set<MetricType> readOnly;
-
-        MetricRegistry() {
-            metricTypes.add(Field.ClientExecuteTime);
-            metricTypes.add(Field.Exception);
-            metricTypes.add(Field.ThrottleException);
-            metricTypes.add(Field.HttpClientRetryCount);
-            metricTypes.add(Field.HttpRequestTime);
-            metricTypes.add(Field.RequestCount);
-//            metricTypes.add(Field.RequestSigningTime);
-//            metricTypes.add(Field.ResponseProcessingTime);
-            metricTypes.add(Field.RetryCount);
-            metricTypes.add(Field.RetryCapacityConsumed);
-            metricTypes.add(Field.ThrottledRetryCount);
-            metricTypes.add(Field.HttpClientSendRequestTime);
-            metricTypes.add(Field.HttpClientReceiveResponseTime);
-            metricTypes.add(Field.HttpSocketReadTime);
-            metricTypes.add(Field.HttpClientPoolAvailableCount);
-            metricTypes.add(Field.HttpClientPoolLeasedCount);
-            metricTypes.add(Field.HttpClientPoolPendingCount);
-            metricTypes.add(AWSServiceMetrics.HttpClientGetConnectionTime);
-            syncReadOnly();
-        }
-
-        private void syncReadOnly() {
-            readOnly = Collections.unmodifiableSet(new HashSet<MetricType>(metricTypes));
-        }
-
-        public boolean addMetricType(MetricType type) {
-            synchronized(metricTypes) {
-                boolean added = metricTypes.add(type);
-                if (added)
-                    syncReadOnly();
-                return added;
-            }
-        }
-        public <T extends MetricType> boolean addMetricTypes(Collection<T> types) {
-            synchronized(metricTypes) {
-                boolean added = metricTypes.addAll(types);
-                if (added)
-                    syncReadOnly();
-                return added;
-            }
-        }
-        public <T extends MetricType> void setMetricTypes(Collection<T> types) {
-            synchronized(metricTypes) {
-                if (types == null || types.size() == 0) {
-                    if (metricTypes.size() == 0)
-                        return;
-                    if (types == null)
-                        types = Collections.emptyList();
-                }
-                metricTypes.clear();
-                if (!addMetricTypes(types)) {
-                    syncReadOnly(); // avoid missing sync
-                }
-            }
-        }
-        public boolean removeMetricType(MetricType type) {
-            synchronized(metricTypes) {
-                boolean removed = metricTypes.remove(type);
-                if (removed)
-                    syncReadOnly();
-                return removed;
-            }
-        }
-        public Set<MetricType> predefinedMetrics() {
-            return readOnly;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/ByteThroughputHelper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ByteThroughputHelper.java
--- ./src/main/java/com/amazonaws/metrics/ByteThroughputHelper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ByteThroughputHelper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Helper class to capture the byte throughput.
- * <p>
- * Note this class is only relevant
- * when metric is enabled. Otherwise it should not even be involved in the call
- * stack to minimize runtime overhead.
- */
-class ByteThroughputHelper extends ByteThroughputProvider {
-    private static final int REPORT_INTERVAL_SECS = 10;
-
-    ByteThroughputHelper(ThroughputMetricType type) {
-        super(type);
-    }
-
-    long startTiming() {
-        if (TimeUnit.NANOSECONDS.toSeconds(getDurationNano()) > REPORT_INTERVAL_SECS) {
-            reportMetrics();
-        }
-        return System.nanoTime();
-    }
-    
-
-    void reportMetrics() {
-        if (getByteCount() > 0) {
-            ServiceMetricCollector col = AwsSdkMetrics.getServiceMetricCollector();
-            col.collectByteThroughput(this);
-            reset();
-        }
-    }
-
-    @Override
-    public void increment(int bytesDelta, long startTimeNano) {
-        super.increment(bytesDelta, startTimeNano);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/ByteThroughputProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ByteThroughputProvider.java
--- ./src/main/java/com/amazonaws/metrics/ByteThroughputProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ByteThroughputProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,57 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-/**
- * Byte throughput metric information provider.
- */
-public abstract class ByteThroughputProvider {
-    private long duration;
-    private int byteCount;
-    private final ThroughputMetricType throughputType;
-
-    protected ByteThroughputProvider(ThroughputMetricType type) { this.throughputType = type; }
-    public ThroughputMetricType getThroughputMetricType() { return throughputType; }
-    public int getByteCount() { return byteCount; }
-    public long getDurationNano() { return duration; }
-    
-    /**
-     * Returns a provider id that can be used to compute the number of active
-     * byte throughput provider of a specific metric type being active in a
-     * given time interval.
-     */
-    public String getProviderId() { return super.toString(); }
-    
-    /**
-     * @param bytesDelta the number of bytes to increment
-     * @param startTimeNano the start time in nano seconds
-     */
-    protected void increment(int bytesDelta, long startTimeNano) {
-        this.byteCount += bytesDelta;
-        this.duration += System.nanoTime() - startTimeNano;
-    }
-    
-    protected void reset() {
-        this.byteCount = 0;
-        this.duration = 0;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "providerId=%s, throughputType=%s, byteCount=%d, duration=%d",
-                getProviderId(), throughputType, byteCount, duration);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/internal/ServiceMetricTypeGuesser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/internal/ServiceMetricTypeGuesser.java
--- ./src/main/java/com/amazonaws/metrics/internal/ServiceMetricTypeGuesser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/internal/ServiceMetricTypeGuesser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics.internal;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.Request;
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.metrics.ServiceMetricType;
-import com.amazonaws.metrics.SimpleThroughputMetricType;
-import com.amazonaws.metrics.ThroughputMetricType;
-
-/**
- * An internal helper factory for generating service specific {@link ServiceMetricType}
- * without causing compile time dependency on the service specific artifacts.
- * 
- * There exists a S3ServiceMetricTest.java unit test in the S3 client library
- * that ensures this class behaves consistently with the service metric enum
- * defined in the S3 client library.
- */
-public enum ServiceMetricTypeGuesser {
-    ;
-    /**
-     * Returned the best-guessed throughput metric type for the given request,
-     * or null if there is none or if metric is disabled.
-     */
-    public static ThroughputMetricType guessThroughputMetricType(
-            final Request<?> req,
-            final String metricNameSuffix,
-            final String byteCountMetricNameSuffix)
-    {
-        if (!AwsSdkMetrics.isMetricsEnabled())
-            return null;    // metric disabled
-        Object orig = req.getOriginalRequestObject();
-        if (orig.getClass().getName().startsWith("com.amazonaws.services.s3")) {
-            return new SimpleThroughputMetricType(
-                "S3" + metricNameSuffix,
-                req.getServiceName(),
-                "S3" + byteCountMetricNameSuffix);
-        }
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/MetricAdmin.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricAdmin.java
--- ./src/main/java/com/amazonaws/metrics/MetricAdmin.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricAdmin.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,142 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.metrics;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import com.amazonaws.regions.Regions;
-
-/**
- *  Administration of AwsSdkMetrics as an MBean.
- */
-public class MetricAdmin implements MetricAdminMBean {
-    @Override
-    public boolean enableDefaultMetrics() {
-        return AwsSdkMetrics.enableDefaultMetrics();
-    }
-    @Override
-    public void disableMetrics() {
-        AwsSdkMetrics.disableMetrics();
-    }
-    @Override
-    public String getRequestMetricCollector() {
-        MetricCollector mc = AwsSdkMetrics.getInternalMetricCollector();
-        RequestMetricCollector rmc = mc == null ? null : mc.getRequestMetricCollector();
-        return mc == null || rmc == RequestMetricCollector.NONE
-             ? "NONE"
-             : rmc.getClass().getName()
-             ;
-    }
-    @Override
-    public String getServiceMetricCollector() {
-        MetricCollector mc = AwsSdkMetrics.getInternalMetricCollector();
-        ServiceMetricCollector smc = mc == null ? null : mc.getServiceMetricCollector();
-        return mc == null || smc == ServiceMetricCollector.NONE
-             ? "NONE"
-             : smc.getClass().getName()
-             ;
-    }
-    @Override
-    public boolean isMetricsEnabled() {
-        return AwsSdkMetrics.isMetricsEnabled();
-    }
-
-    @Override
-    public boolean isMachineMetricsExcluded() {
-        return AwsSdkMetrics.isMachineMetricExcluded();
-    }
-    @Override
-    public void setMachineMetricsExcluded(boolean excludeJvmMetrics) {
-        AwsSdkMetrics.setMachineMetricsExcluded(excludeJvmMetrics);
-    }
-    @Override
-    public String getRegion() {
-        return AwsSdkMetrics.getRegionName();
-    }
-    @Override
-    public void setRegion(String region) {
-        AwsSdkMetrics.setRegion(region);
-    }
-    @Override
-    public Integer getMetricQueueSize() {
-        return AwsSdkMetrics.getMetricQueueSize();
-    }
-    @Override
-    public void setMetricQueueSize(Integer metricQueueSize) {
-        AwsSdkMetrics.setMetricQueueSize(metricQueueSize);
-
-    }
-    @Override
-    public Integer getQueuePollTimeoutMilli() {
-        Long queuePollTimeoutMilli = AwsSdkMetrics.getQueuePollTimeoutMilli();
-        return queuePollTimeoutMilli == null ? null : queuePollTimeoutMilli.intValue();
-    }
-    @Override
-    public void setQueuePollTimeoutMilli(Integer timeoutMilli) {
-        AwsSdkMetrics.setQueuePollTimeoutMilli(timeoutMilli == null ? null : timeoutMilli.longValue());
-    }
-    @Override
-    public String getMetricNameSpace() {
-        return AwsSdkMetrics.getMetricNameSpace();
-    }
-    @Override
-    public void setMetricNameSpace(String metricNameSpace) {
-        AwsSdkMetrics.setMetricNameSpace(metricNameSpace);
-    }
-
-    @Override
-    public boolean isPerHostMetricsIncluded() {
-        return AwsSdkMetrics.isPerHostMetricIncluded();
-    }
-    @Override
-    public void setPerHostMetricsIncluded(boolean includePerHostMetrics) {
-        AwsSdkMetrics.setPerHostMetricsIncluded(includePerHostMetrics);
-    }
-    @Override
-    public String getJvmMetricName() {
-        return AwsSdkMetrics.getJvmMetricName();
-    }
-    @Override
-    public void setJvmMetricName(String jvmMetricName) {
-        AwsSdkMetrics.setJvmMetricName(jvmMetricName);
-    }
-    @Override
-    public String getHostMetricName() {
-        return AwsSdkMetrics.getHostMetricName();
-    }
-    @Override
-    public void setHostMetricName(String hostMetricName) {
-        AwsSdkMetrics.setHostMetricName(hostMetricName);
-    }
-    @Override
-    public String getCredentialFile() {
-        return AwsSdkMetrics.getCredentailFile();
-    }
-
-    @Override
-    public void setCredentialFile(String filepath)
-            throws FileNotFoundException, IOException {
-        AwsSdkMetrics.setCredentialFile(filepath);
-    }
-    @Override
-    public boolean isSingleMetricNamespace() {
-        return AwsSdkMetrics.isSingleMetricNamespace();
-    }
-    @Override
-    public void setSingleMetricNamespace(boolean singleMetricNamespace) {
-        AwsSdkMetrics.setSingleMetricNamespace(singleMetricNamespace);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/MetricAdminMBean.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricAdminMBean.java
--- ./src/main/java/com/amazonaws/metrics/MetricAdminMBean.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricAdminMBean.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,187 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.metrics;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.InetAddress;
-
-/**
- * MBean interface for AwsSdkMetrics administration.
- */
-public interface MetricAdminMBean {
-    /**
-     * Returns true if metrics at the AWS SDK level is enabled; false if
-     * disabled.
-     */
-    public boolean isMetricsEnabled();
-
-    /**
-     * Returns the name of the request metric collector set at the AWS SDK
-     * level, or NONE if there is none.
-     */
-    public String getRequestMetricCollector();
-
-    /**
-     * Returns the name of the service metric collector set at the AWS SDK
-     * level, or NONE if there is none.
-     */
-    public String getServiceMetricCollector();
-
-    /**
-     * Starts the default AWS SDK metric collector, but only if no metric
-     * collector is currently in use at the AWS SDK level.
-     * 
-     * @return true if the default AWS SDK metric collector has been
-     *         successfully started by this call; false otherwise.
-     */
-    public boolean enableDefaultMetrics();
-
-    /**
-     * Disables the metric collector at the AWS SDK level.
-     */
-    public void disableMetrics();
-
-    /**
-     * Returns true if machine metrics is to be excluded; false otherwise.
-     */
-    public boolean isMachineMetricsExcluded();
-
-    /**
-     * Used to set whether the JVM metrics is to be excluded.
-     * 
-     * @param excludeMachineMetrics
-     *            true if JVM metrics is to be excluded; false otherwise.
-     */
-    public void setMachineMetricsExcluded(boolean excludeMachineMetrics);
-
-    /**
-     * Returns true if per-host metrics is to be included; false otherwise.
-     */
-    public boolean isPerHostMetricsIncluded();
-
-    /**
-     * Used to set whether the per-host metrics is to be included.
-     * 
-     * @param includePerHostMetrics
-     *            true if per-host metrics is to be included; false otherwise.
-     */
-    public void setPerHostMetricsIncluded(boolean includePerHostMetrics);
-
-    /**
-     * Returns the region configured for the default AWS SDK metric collector;
-     * or null if the default is to be used.
-     */
-    public String getRegion();
-
-    /**
-     * Sets the region to be used for the default AWS SDK metric collector; or
-     * null if the default is to be used.
-     */
-    public void setRegion(String region);
-
-    /**
-     * Returns the last set AWS credential file; or null if there is none.
-     */
-    public String getCredentialFile();
-
-    /**
-     * Sets the AWS credential file used by the default AWS SDK metric collector
-     * for accessing CloudWatch.
-     * 
-     * @param filepath
-     *            must be a valid path to an AWS credential property file.
-     */
-    public void setCredentialFile(String filepath)
-        throws FileNotFoundException, IOException;
-
-    /**
-     * Returns the internal metric queue size to be used for the default AWS SDK
-     * metric collector; or null if the default is to be used.
-     */
-    public Integer getMetricQueueSize();
-
-    /**
-     * Sets the metric queue size to be used for the default AWS SDK metric
-     * collector; or null if the default is to be used.
-     */
-    public void setMetricQueueSize(Integer metricQueueSize);
-
-    /**
-     * Returns the internal metric queue timeout in millisecond to be used for
-     * the default AWS SDK metric collector; or null if the default is to be
-     * used. Use Integer instead of Long as it seems jconsole does not handle
-     * Long properly.
-     */
-    public Integer getQueuePollTimeoutMilli();
-
-    /**
-     * Sets the queue poll time in millisecond to be used for the default AWS
-     * SDK metric collector; or null if the default is to be used. Use Integer
-     * instead of Long as it seems jconsole does not handle Long properly.
-     */
-    public void setQueuePollTimeoutMilli(Integer timeoutMilli);
-
-    /**
-     * Returns the metric name space.
-     */
-    public String getMetricNameSpace();
-
-    /**
-     * Sets the metric name space.
-     * 
-     * @throws IllegalArgumentException
-     *             if the given name space is either null or blank.
-     */
-    public void setMetricNameSpace(String metricNameSpace);
-
-    /**
-     * Returns the JVM metric name. If the returned value is either null or
-     * blank, no JVM level metrics will be generated.
-     */
-    public String getJvmMetricName();
-
-    /**
-     * Sets the JVM metric name to enable per-JVM level metrics generation. If
-     * the given value is either null or blank, no JVM level metrics will be
-     * generated.
-     */
-    public void setJvmMetricName(String jvmMetricName);
-
-    /**
-     * Returns the host name for metric purposes. If the returned value is
-     * either null or blank, the host name will be automatically detected via
-     * {@link InetAddress}.
-     */
-    public String getHostMetricName();
-
-    /**
-     * Sets the host name to enable per-host level metrics generation. If
-     * the given value is either null or blank but the per-host metric is
-     * enabled, the host name will be automatically detected via
-     * {@link InetAddress}.
-     */
-    public void setHostMetricName(String hostMetricName);
-
-    /**
-     * Returns true if single metric name space is to be used; false otherwise.
-     */
-    public boolean isSingleMetricNamespace();
-
-    /**
-     * Used to set whether a single metric name space is to be used.
-     */
-    public void setSingleMetricNamespace(boolean singleMetricNamespace);
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/metrics/MetricCollector.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricCollector.java
--- ./src/main/java/com/amazonaws/metrics/MetricCollector.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricCollector.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,67 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-
-/**
- * Metric Collector SPI.  This is a class instead of interface so in case of
- * adding new methods in the future we can do that safetly without breaking
- * any existing clients that implements this SPI.
- */
-public abstract class MetricCollector 
-{
-    /**
-     * Can be used to serve as a factory for the request metric collector.
-     */
-    public static interface Factory {
-        /**
-         * Returns an instance of the collector; or null if if failed to create
-         * one.
-         */
-        public MetricCollector getInstance();
-    }
-    /**
-     * Starts the request metric collector.
-     * 
-     * @return true if the collector is successfully started; false otherwise.
-     */
-    public abstract boolean start();
-
-    /** 
-     * Stops the request metric collector.
-     *
-     * @return true if the collector is successfully stopped; false if the
-     *         collector is not running and therefore the call has no effect.
-     */
-    public abstract boolean stop();
-    /** Returns true if this collector is enabled; false otherwise. */
-    public abstract boolean isEnabled();
-    public abstract RequestMetricCollector getRequestMetricCollector();
-    public abstract ServiceMetricCollector getServiceMetricCollector();
-
-    /** A convenient instance of a no-op request metric collector. */
-    public static final MetricCollector NONE = new MetricCollector() {
-        @Override public boolean start() { return true; }
-        @Override public boolean stop() { return true; }
-        /** Always returns false. */
-        @Override public boolean isEnabled() { return false; }
-        @Override public RequestMetricCollector getRequestMetricCollector() {
-            return RequestMetricCollector.NONE;
-        }
-        @Override public ServiceMetricCollector getServiceMetricCollector() {
-            return ServiceMetricCollector.NONE;
-        }
-    };
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/MetricFilterInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricFilterInputStream.java
--- ./src/main/java/com/amazonaws/metrics/MetricFilterInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricFilterInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * Used to capture the input stream throughput metrics, but excluding the
- * {@link #read()} API.
- * <p>
- * Note this class is only relevant
- * when metric is enabled. Otherwise it should not even be involved in the call
- * stack to minimize runtime overhead.
- */
-public class MetricFilterInputStream extends SdkFilterInputStream {
-    private final ByteThroughputHelper helper;
-
-    public MetricFilterInputStream(ThroughputMetricType type, InputStream in) {
-        super(in);
-        helper = new ByteThroughputHelper(type);
-    }
-
-    @Override
-    public int read(byte b[], int off, int len) throws IOException {
-        abortIfNeeded();
-        long startNano = helper.startTiming();
-        int bytesRead = in.read(b, off, len);
-        if (bytesRead > 0) {
-            helper.increment(bytesRead, startNano);
-        }
-        return bytesRead;
-    }
-
-    @Override
-    public void close() throws IOException {
-        helper.reportMetrics();
-        in.close();
-        abortIfNeeded();
-    }
-
-    @Override
-    public final boolean isMetricActivated() {
-        return true;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/MetricInputStreamEntity.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricInputStreamEntity.java
--- ./src/main/java/com/amazonaws/metrics/MetricInputStreamEntity.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricInputStreamEntity.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,106 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.InputStreamEntity;
-
-import com.amazonaws.internal.MetricAware;
-
-/**
- * Used to help capture the throughput metrics.
- * <p>
- * Note this class is only relevant
- * when metric is enabled. Otherwise it should not even be involved in the call
- * stack to minimize runtime overhead.
- */
-public class MetricInputStreamEntity extends InputStreamEntity {
-    private final static int BUFFER_SIZE = 2048;
-    private final ByteThroughputHelper helper;
-
-    public MetricInputStreamEntity(ThroughputMetricType metricType,
-            InputStream instream, long length) {
-        super(instream, length);
-        helper = new ByteThroughputHelper(metricType);
-    }
-
-    public MetricInputStreamEntity(ThroughputMetricType metricType,
-            final InputStream instream, long length,
-            final ContentType contentType) {
-        super(instream, length, contentType);
-        helper = new ByteThroughputHelper(metricType);
-    }
-
-    @Override
-    public void writeTo(final OutputStream outstream) throws IOException {
-        if (outstream instanceof MetricAware) {
-            // hchar: There is currently no implementation of output stream that
-            // has metric gathering capability but there could be!
-            // So the code here is for future proof purposes.
-            MetricAware aware = (MetricAware)outstream;
-            if (aware.isMetricActivated()) {
-                // let the underlying output stream takes care of byte counting
-                super.writeTo(outstream);
-                return;
-            }
-        }
-        writeToWithMetrics(outstream);
-    }
-
-    /**
-     * Copied from {{@link InputStreamEntity#writeTo(OutputStream)} but modified
-     * to capture metrics for the output stream.
-     */
-    private void writeToWithMetrics(final OutputStream outstream) throws IOException {
-        if (outstream == null) {
-            throw new IllegalArgumentException("Output stream may not be null");
-        }
-        final InputStream content = getContent();
-        final long length = getContentLength();
-        InputStream instream = content;
-        try {
-            byte[] buffer = new byte[BUFFER_SIZE];
-            int l;
-            if (length < 0) {
-                // consume until EOF
-                while ((l = instream.read(buffer)) != -1) {
-                    long startNano = helper.startTiming();
-                    outstream.write(buffer, 0, l);
-                    helper.increment(l, startNano);
-                }
-            } else {
-                // consume no more than length
-                long remaining = length;
-                while (remaining > 0) {
-                    l = instream.read(buffer, 0, (int)Math.min(BUFFER_SIZE, remaining));
-                    if (l == -1) {
-                        break;
-                    }
-                    long startNano = helper.startTiming();
-                    outstream.write(buffer, 0, l);
-                    helper.increment(l, startNano);
-                    remaining -= l;
-                }
-            }
-        } finally {
-            helper.reportMetrics();
-            instream.close();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/MetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricType.java
--- ./src/main/java/com/amazonaws/metrics/MetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/MetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-/**
- * Metric type.
- */
-public interface MetricType {
-    /**
-     * Non-null name of the metric type. Used to uniquely identify the metric
-     * type. Therefore, the name returned must be globally unique across all
-     * metric types that implement this interface.
-     */
-    public String name();
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/package-info.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/package-info.java
--- ./src/main/java/com/amazonaws/metrics/package-info.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/package-info.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,120 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-/**
- * Classes used to support the AWS SDK metrics API.
- * 
- * When the default metric collection system is enabled, 
- * the default AWS SDK implementation
- * captures a set of predefined core metrics that are grouped under three major 
- * categories:  AWS Request Metrics, AWS Service Metrics, and Machine Metrics.
- * <h3>Nomenclature</h3>
- * <ul>
- * <li>Physical Http Request - an http request initiated by the http client library used by AWS Java SDK . No retry is involved, or at least not initiated from the JVM.</li>
- * <li>Logical Http Request - an http request initiated from the AWS Java SDK by executing the underlying http client library. A logical request may involve multiple physical requests due to retries.</li>
- * <li>Service Client type - the specific subtype of AmazonWebServiceClient, such as AmazonS3Client, AmazonDynamoDBClient, etc.</li>
- * <li>Request type - the specific subtype of AmazonWebServiceRequest, such as PutItemRequest, PutObjectRequest, etc.</li>
- * <li>Http Client Library - the <a href="http://hc.apache.org/httpcomponents-client-4.2.x/index.html">Apache HttpComponents client</a> library</li>
- * </ul>
- * 
- * <h3>AWS Request Metrics</h3>
- * <ol>
- * <li>ClientExecuteTime - Total number of milliseconds taken for a 
- * request/response including the time taken to execute the request handlers,
- * round trip to AWS, and the time taken to execute the response handlers.
- * Captured on a per request type level.</li>
- * <li>Exception - Number of logical request failure. Captured both on a per service 
- * client type level and a per request type level.</li>
- * <li>HttpClientPoolAvailableCount - Number of idle persistent connections of
- * the underlying httpclient.
- * This metric is collected from the respective <a 
- * href="https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/pool/PoolStats.html"
- * >PoolStats</a> before the connection of a request is obtained.</li>
- * <li>HttpClientPoolLeasedCount - Number of persistent connections tracked by 
- * the underlying httpclient connection manager currently being used to execute
- * requests.
- * This metric is collected from the respective <a 
- * href="https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/pool/PoolStats.html"
- * >PoolStats</a> before the connection of a request is obtained.</li>
- * <li>HttpClientPoolPendingCount - Number of connection requests being blocked
- * awaiting a free connection of the underlying httpclient.
- * This metric is collected from the respective <a 
- * href="https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/pool/PoolStats.html"
- * >PoolStats</a>. before the connection of a request is obtained</li>
- * <li>HttpRequestTime - Number of milliseconds taken for a logical request/response 
- * round trip to AWS. Captured on a per request type level.</li>
- * <li>HttpClientSendRequestTime - Number of milliseconds taken for a physical request
- * to get sent to AWS. Captured on a per request type level.</li>
- * <li>HttpClientReceiveResponseTime - Number of milliseconds taken for a physical response
- * to get received from AWS. Captured on a per request type level.</li>
- * <li>HttpClientRetryCount - Number of retries per physical request. Captured on a per service 
- * client type level. </li>
- * <li>RequestCount - Number of logical requests. Captured on a per service 
- * client type level. </li>
- * <li>RetryCount - Number of retries per logical request. Captured on a per service 
- * client type level. </li>
- * <li>ThrottleException - Number of times of a request has been throttled by the service.</li>
- * <li>DynamoDBConsumedCapacity - Number of Amazon DynamoDB capacity units consumed.
- * Captured on a per request type level, and is only available if the request
- * has been specified with the necessary "ReturnConsumedCapacity" parameter.
- * </li>
- * </ol>
- * <h3>AWS Service Metrics</h3>
- * <ol>
- * <li>HttpClientGetConnectionTime - Total number of milliseconds taken for the
- * underlying http client library to get a connection.
- * <li>S3DownloadThroughput - Number of bytes downloaded from S3 per second.</li>
- * <li>S3DownloadByteCount - Number of bytes downloaded from S3.</li>
- * <li>S3UploadThroughput - Number of bytes uploaded to S3 per second.</li>
- * <li>S3UploadByteCount - Number of bytes uploaded to S3.</li>
- * </ol>
- * <h3>Machine Metrics</h3>
- * <h4>Memory</h4>
- * <ol>
- * <li>TotalMemory - Total amount of memory currently available to the JVM for
- * current and future objects, measured in bytes. This value may vary over 
- * time, depending on the host environment.</li>
- * <li>FreeMemory - An approximation to the total amount of memory currently 
- * available to the JVM for future allocated objects, measured in bytes.</li>
- * <li>UsedMemory - TotalMemory minus FreeMemory.</li>
- * <li>SpareMemory - The maximum amount of memory that the JVM will attempt to
- * use, measured in bytes, minus UsedMemory. </li>
- * </ol>
- * <h4>Threads</h4>
- * <ol>
- * <li>ThreadCount - The current number of live threads including both daemon 
- * and non-daemon threads.</li>
- * <li>DeadLockThreadCount - The number of threads that are deadlocked waiting 
- * for object monitors or ownable synchronizers, if any. Threads are deadlocked
- *  in a cycle waiting for a lock of these two types if each thread owns one 
- *  lock while trying to acquire another lock already held by another thread in
- *   the cycle. No metrics is generated when the value is zero.</li>
- * <li>DaemonThreadCount - The current number of live daemon threads. No metrics
- *  is generated when the value is zero.</li>
- * <li>PeakThreadCount - The peak live thread count since the JVM started or 
- * since the peak was reset.</li>
- * <li>TotalStartedThreadCount - The total number of threads created and also 
- * started since the JVM started.</li>
- * </ol>
- * <h4>File Descriptors</h4>
- * <ol>
- * <li>OpenFileDescriptorCount - Number of opened file descriptors of the 
- * operating system.</li>
- * <li>SpareFileDescriptorCount - Maximum number of file descriptors of the 
- * operating system minus OpenFileDescriptorCount.</li>
- * </ol>
- */
-package com.amazonaws.metrics;
-
diff -Nau8r ./src/main/java/com/amazonaws/metrics/RequestMetricCollector.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/RequestMetricCollector.java
--- ./src/main/java/com/amazonaws/metrics/RequestMetricCollector.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/RequestMetricCollector.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,51 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.metrics;
-
-import com.amazonaws.Request;
-import com.amazonaws.Response;
-
-/**
- * A service provider interface that can be used to implement an AWS SDK
- * request/response metric collector.
- * 
- * @see AwsSdkMetrics
- */
-public abstract class RequestMetricCollector {
-    /**
-     * Can be used to serve as a factory for the request metric collector.
-     */
-    public static interface Factory {
-        /**
-         * Returns an instance of the collector; or null if if failed to create
-         * one.
-         */
-        public RequestMetricCollector getRequestMetricCollector();
-    }
-    /** 
-     * Used to collect the metric at the end of a request/response cycle.
-     *
-     * @see Request#getAWSRequestMetrics()
-     */
-    public abstract void collectMetrics(Request<?> request, Response<?> response);
-    public boolean isEnabled() { return true; }
-
-    /** A convenient instance of a no-op request metric collector. */
-    public static final RequestMetricCollector NONE = new RequestMetricCollector() {
-        @Override public void collectMetrics(Request<?> request, Response<?> response) {}
-        @Override public boolean isEnabled() { return false; }
-    };
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/RequestMetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/RequestMetricType.java
--- ./src/main/java/com/amazonaws/metrics/RequestMetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/RequestMetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,23 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-/**
- * <a href=
- * "http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/metrics/package-summary.html"
- * >Request metric type</a>.
- */
-public interface RequestMetricType extends MetricType {
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/ServiceLatencyProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ServiceLatencyProvider.java
--- ./src/main/java/com/amazonaws/metrics/ServiceLatencyProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ServiceLatencyProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,63 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.util.TimingInfo;
-
-/**
- * Latency metric information provider.
- */
-@NotThreadSafe
-public class ServiceLatencyProvider {
-    private final long startNano = System.nanoTime();
-    private long endNano = startNano;
-    private final ServiceMetricType serviceMetricType;
-
-    public ServiceLatencyProvider(ServiceMetricType type) { 
-        this.serviceMetricType = type;
-    }
-    public ServiceMetricType getServiceMetricType() { return serviceMetricType; }
-
-    /**
-     * Ends the timing.  Must not be called more than once.
-     */
-    public ServiceLatencyProvider endTiming() {
-        if (endNano != startNano) {
-            throw new IllegalStateException();
-        }
-        endNano = System.nanoTime();
-        return this; 
-    }
-
-    public double getDurationMilli() {
-        if (endNano == startNano) {
-            LogFactory.getLog(getClass()).debug(
-                    "Likely to be a missing invocation of endTiming().");
-        }
-        return TimingInfo.durationMilliOf(startNano, endNano); 
-    }
-    
-    public String getProviderId() { return super.toString(); }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "providerId=%s, serviceMetricType=%s, startNano=%d, endNano=%d", 
-                getProviderId(), serviceMetricType, startNano, endNano);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/ServiceMetricCollector.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ServiceMetricCollector.java
--- ./src/main/java/com/amazonaws/metrics/ServiceMetricCollector.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ServiceMetricCollector.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-/**
- * A service provider interface that can be used to implement an AWS SDK
- * general purpose metric collector.
- */
-public abstract class ServiceMetricCollector {
-    public static interface Factory {
-        /**
-         * Returns an instance of the collector; or null if if failed to create
-         * one.
-         */
-        public ServiceMetricCollector getServiceMetricCollector();
-    }
-    /**
-     * Collects metrics on the number of bytes written or read and the respective
-     * duration.
-     */
-    public abstract void collectByteThroughput(ByteThroughputProvider provider);
-    /**
-     * Collects metrics for non-request specific latencies.
-     */
-    public abstract void collectLatency(ServiceLatencyProvider provider);
-
-    public boolean isEnabled() { return true; }
-    /** A convenient instance of a no-op service metric collector. */
-    public static final ServiceMetricCollector NONE = new ServiceMetricCollector() {
-        @Override public void collectByteThroughput(ByteThroughputProvider provider) {}
-        @Override public void collectLatency(ServiceLatencyProvider provider) {}
-        @Override public boolean isEnabled() { return false; }
-    };
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/ServiceMetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ServiceMetricType.java
--- ./src/main/java/com/amazonaws/metrics/ServiceMetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ServiceMetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-/**
- * <a href=
- * "http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/metrics/package-summary.html"
- * >Service specific Metric type</a> (eg S3, DynamoDB, etc.)
- */
-public interface ServiceMetricType extends MetricType {
-    public String getServiceName();
-
-    public static final String UPLOAD_THROUGHPUT_NAME_SUFFIX = "UploadThroughput";
-    public static final String UPLOAD_BYTE_COUNT_NAME_SUFFIX = "UploadByteCount";
-    public static final String DOWNLOAD_THROUGHPUT_NAME_SUFFIX = "DownloadThroughput";
-    public static final String DOWNLOAD_BYTE_COUNT_NAME_SUFFIX = "DownloadByteCount";
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/SimpleMetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/SimpleMetricType.java
--- ./src/main/java/com/amazonaws/metrics/SimpleMetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/SimpleMetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-public abstract class SimpleMetricType implements MetricType {
-    @Override public abstract String name();
-
-    @Override public final int hashCode() { return name().hashCode(); }
-    @Override public final boolean equals(Object o) {
-        if (!(o instanceof MetricType))
-            return false;
-        MetricType that = (MetricType)o;
-        return this.name().equals(that.name());
-    }
-    @Override public final String toString() { return name(); }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/SimpleServiceMetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/SimpleServiceMetricType.java
--- ./src/main/java/com/amazonaws/metrics/SimpleServiceMetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/SimpleServiceMetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-public class SimpleServiceMetricType extends SimpleMetricType implements ServiceMetricType {
-    private final String name;
-    private final String serviceName;
-    public SimpleServiceMetricType(String name, String serviceName) {
-        this.name = name;
-        this.serviceName = serviceName;
-    }
-    @Override public String name() { return name; }
-    @Override public String getServiceName() { return serviceName; }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/SimpleThroughputMetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/SimpleThroughputMetricType.java
--- ./src/main/java/com/amazonaws/metrics/SimpleThroughputMetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/SimpleThroughputMetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-public class SimpleThroughputMetricType extends SimpleServiceMetricType implements ThroughputMetricType {
-    private final ServiceMetricType byteCountMetricType;
-    public SimpleThroughputMetricType(String name, String serviceName, String byteCountMetricName) {
-        super(name, serviceName);
-        this.byteCountMetricType = new SimpleServiceMetricType(byteCountMetricName, serviceName);
-    }
-
-    @Override public ServiceMetricType getByteCountMetricType() {
-        return byteCountMetricType;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/metrics/ThroughputMetricType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ThroughputMetricType.java
--- ./src/main/java/com/amazonaws/metrics/ThroughputMetricType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/metrics/ThroughputMetricType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,19 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.metrics;
-
-public interface ThroughputMetricType extends ServiceMetricType {
-    public ServiceMetricType getByteCountMetricType();
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/endpoints.json /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/endpoints.json
--- ./src/main/java/com/amazonaws/partitions/endpoints.json	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/endpoints.json	1969-12-31 16:00:00.000000000 -0800
@@ -1,2555 +0,0 @@
-{
-  "partitions" : [ {
-    "defaults" : {
-      "hostname" : "{service}.{region}.{dnsSuffix}",
-      "protocols" : [ "https" ],
-      "signatureVersions" : [ "v4" ]
-    },
-    "dnsSuffix" : "amazonaws.com",
-    "partition" : "aws",
-    "partitionName" : "AWS Standard",
-    "regionRegex" : "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$",
-    "regions" : {
-      "ap-northeast-1" : {
-        "description" : "Asia Pacific (Tokyo)"
-      },
-      "ap-northeast-2" : {
-        "description" : "Asia Pacific (Seoul)"
-      },
-      "ap-south-1" : {
-        "description" : "Asia Pacific (Mumbai)"
-      },
-      "ap-southeast-1" : {
-        "description" : "Asia Pacific (Singapore)"
-      },
-      "ap-southeast-2" : {
-        "description" : "Asia Pacific (Sydney)"
-      },
-      "ca-central-1" : {
-        "description" : "Canada (Central)"
-      },
-      "eu-central-1" : {
-        "description" : "EU (Frankfurt)"
-      },
-      "eu-west-1" : {
-        "description" : "EU (Ireland)"
-      },
-      "eu-west-2" : {
-        "description" : "EU (London)"
-      },
-      "eu-west-3" : {
-        "description" : "EU (Paris)"
-      },
-      "sa-east-1" : {
-        "description" : "South America (Sao Paulo)"
-      },
-      "us-east-1" : {
-        "description" : "US East (N. Virginia)"
-      },
-      "us-east-2" : {
-        "description" : "US East (Ohio)"
-      },
-      "us-west-1" : {
-        "description" : "US West (N. California)"
-      },
-      "us-west-2" : {
-        "description" : "US West (Oregon)"
-      }
-    },
-    "services" : {
-      "a4b" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "acm" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "api.pricing" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "pricing"
-          }
-        },
-        "endpoints" : {
-          "ap-south-1" : { },
-          "us-east-1" : { }
-        }
-      },
-      "apigateway" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "application-autoscaling" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "application-autoscaling"
-          },
-          "hostname" : "autoscaling.{region}.amazonaws.com",
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "appstream2" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "appstream"
-          },
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "athena" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "autoscaling" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "autoscaling-plans" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "autoscaling-plans"
-          },
-          "hostname" : "autoscaling.{region}.amazonaws.com",
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-southeast-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "batch" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "budgets" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "budgets.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "ce" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "ce.us-east-1.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "cloud9" : {
-        "endpoints" : {
-          "ap-southeast-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "clouddirectory" : {
-        "endpoints" : {
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cloudformation" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cloudfront" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "cloudfront.amazonaws.com",
-            "protocols" : [ "http", "https" ]
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "cloudhsm" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cloudhsmv2" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "cloudhsm"
-          }
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cloudsearch" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cloudtrail" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "codebuild" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "codecommit" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "codedeploy" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "codepipeline" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "codestar" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cognito-identity" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cognito-idp" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cognito-sync" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "comprehend" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "config" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "cur" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "data.iot" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "iotdata"
-          },
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "datapipeline" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "dax" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "devicefarm" : {
-        "endpoints" : {
-          "us-west-2" : { }
-        }
-      },
-      "directconnect" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "discovery" : {
-        "endpoints" : {
-          "us-west-2" : { }
-        }
-      },
-      "dms" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "ds" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "dynamodb" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "local" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "localhost:8000",
-            "protocols" : [ "http" ]
-          },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "ec2" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "ecr" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "ecs" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "elasticache" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "elasticbeanstalk" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "elasticfilesystem" : {
-        "endpoints" : {
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "elasticloadbalancing" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "elasticmapreduce" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ],
-          "sslCommonName" : "{region}.{service}.{dnsSuffix}"
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : {
-            "sslCommonName" : "{service}.{region}.{dnsSuffix}"
-          },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : {
-            "sslCommonName" : "{service}.{region}.{dnsSuffix}"
-          },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "elastictranscoder" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "email" : {
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "entitlement.marketplace" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "aws-marketplace"
-          }
-        },
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "es" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "events" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "firehose" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "gamelift" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "glacier" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "glue" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "greengrass" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        },
-        "isRegionalized" : true
-      },
-      "guardduty" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        },
-        "isRegionalized" : true
-      },
-      "health" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "iam" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "iam.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "importexport" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1",
-              "service" : "IngestionService"
-            },
-            "hostname" : "importexport.amazonaws.com",
-            "signatureVersions" : [ "v2", "v4" ]
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "inspector" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "iot" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "execute-api"
-          }
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "kinesis" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "kinesisanalytics" : {
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "kinesisvideo" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "kms" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "lambda" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "lightsail" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "logs" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "machinelearning" : {
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { }
-        }
-      },
-      "marketplacecommerceanalytics" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "mediaconvert" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "medialive" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "mediapackage" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-3" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "metering.marketplace" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "aws-marketplace"
-          }
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "mgh" : {
-        "endpoints" : {
-          "us-west-2" : { }
-        }
-      },
-      "mobileanalytics" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "models.lex" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "lex"
-          }
-        },
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { }
-        }
-      },
-      "monitoring" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "mturk-requester" : {
-        "endpoints" : {
-          "sandbox" : {
-            "hostname" : "mturk-requester-sandbox.us-east-1.amazonaws.com"
-          },
-          "us-east-1" : { }
-        },
-        "isRegionalized" : false
-      },
-      "opsworks" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "opsworks-cm" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "organizations" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "organizations.us-east-1.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "pinpoint" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "mobiletargeting"
-          }
-        },
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "polly" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "rds" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : {
-            "sslCommonName" : "{service}.{dnsSuffix}"
-          },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "redshift" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "rekognition" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "resource-groups" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "route53" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "route53.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "route53domains" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "runtime.lex" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "lex"
-          }
-        },
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { }
-        }
-      },
-      "runtime.sagemaker" : {
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "s3" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ],
-          "signatureVersions" : [ "s3v4" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : {
-            "hostname" : "s3.ap-northeast-1.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : {
-            "hostname" : "s3.ap-southeast-1.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "ap-southeast-2" : {
-            "hostname" : "s3.ap-southeast-2.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : {
-            "hostname" : "s3.eu-west-1.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "s3-external-1" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "s3-external-1.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "sa-east-1" : {
-            "hostname" : "s3.sa-east-1.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "us-east-1" : {
-            "hostname" : "s3.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "us-east-2" : { },
-          "us-west-1" : {
-            "hostname" : "s3.us-west-1.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          },
-          "us-west-2" : {
-            "hostname" : "s3.us-west-2.amazonaws.com",
-            "signatureVersions" : [ "s3", "s3v4" ]
-          }
-        },
-        "isRegionalized" : true,
-        "partitionEndpoint" : "us-east-1"
-      },
-      "sagemaker" : {
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "sdb" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ],
-          "signatureVersions" : [ "v2" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "sa-east-1" : { },
-          "us-east-1" : {
-            "hostname" : "sdb.amazonaws.com"
-          },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "serverlessrepo" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : {
-            "protocols" : [ "https" ]
-          },
-          "ap-northeast-2" : {
-            "protocols" : [ "https" ]
-          },
-          "ap-south-1" : {
-            "protocols" : [ "https" ]
-          },
-          "ap-southeast-1" : {
-            "protocols" : [ "https" ]
-          },
-          "ap-southeast-2" : {
-            "protocols" : [ "https" ]
-          },
-          "ca-central-1" : {
-            "protocols" : [ "https" ]
-          },
-          "eu-central-1" : {
-            "protocols" : [ "https" ]
-          },
-          "eu-west-1" : {
-            "protocols" : [ "https" ]
-          },
-          "eu-west-2" : {
-            "protocols" : [ "https" ]
-          },
-          "sa-east-1" : {
-            "protocols" : [ "https" ]
-          },
-          "us-east-1" : {
-            "protocols" : [ "https" ]
-          },
-          "us-east-2" : {
-            "protocols" : [ "https" ]
-          },
-          "us-west-1" : {
-            "protocols" : [ "https" ]
-          },
-          "us-west-2" : {
-            "protocols" : [ "https" ]
-          }
-        }
-      },
-      "servicecatalog" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "servicediscovery" : {
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "shield" : {
-        "defaults" : {
-          "protocols" : [ "https" ],
-          "sslCommonName" : "Shield.us-east-1.amazonaws.com"
-        },
-        "endpoints" : {
-          "us-east-1" : { }
-        },
-        "isRegionalized" : false
-      },
-      "sms" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "snowball" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-south-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "sns" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "sqs" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ],
-          "sslCommonName" : "{region}.queue.{dnsSuffix}"
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : {
-            "sslCommonName" : "queue.{dnsSuffix}"
-          },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "ssm" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "states" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "storagegateway" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "streams.dynamodb" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "dynamodb"
-          },
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "local" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "localhost:8000",
-            "protocols" : [ "http" ]
-          },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "sts" : {
-        "defaults" : {
-          "credentialScope" : {
-            "region" : "us-east-1"
-          },
-          "hostname" : "sts.amazonaws.com"
-        },
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : {
-            "credentialScope" : {
-              "region" : "ap-northeast-2"
-            },
-            "hostname" : "sts.ap-northeast-2.amazonaws.com"
-          },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "aws-global" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-1-fips" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "sts-fips.us-east-1.amazonaws.com"
-          },
-          "us-east-2" : { },
-          "us-east-2-fips" : {
-            "credentialScope" : {
-              "region" : "us-east-2"
-            },
-            "hostname" : "sts-fips.us-east-2.amazonaws.com"
-          },
-          "us-west-1" : { },
-          "us-west-1-fips" : {
-            "credentialScope" : {
-              "region" : "us-west-1"
-            },
-            "hostname" : "sts-fips.us-west-1.amazonaws.com"
-          },
-          "us-west-2" : { },
-          "us-west-2-fips" : {
-            "credentialScope" : {
-              "region" : "us-west-2"
-            },
-            "hostname" : "sts-fips.us-west-2.amazonaws.com"
-          }
-        },
-        "partitionEndpoint" : "aws-global"
-      },
-      "support" : {
-        "endpoints" : {
-          "us-east-1" : { }
-        }
-      },
-      "swf" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "tagging" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "eu-west-3" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "translate" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-2" : { }
-        }
-      },
-      "waf" : {
-        "endpoints" : {
-          "aws-global" : {
-            "credentialScope" : {
-              "region" : "us-east-1"
-            },
-            "hostname" : "waf.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-global"
-      },
-      "waf-regional" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "workdocs" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "workmail" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "eu-west-1" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "workspaces" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "us-east-1" : { },
-          "us-west-2" : { }
-        }
-      },
-      "xray" : {
-        "endpoints" : {
-          "ap-northeast-1" : { },
-          "ap-northeast-2" : { },
-          "ap-south-1" : { },
-          "ap-southeast-1" : { },
-          "ap-southeast-2" : { },
-          "ca-central-1" : { },
-          "eu-central-1" : { },
-          "eu-west-1" : { },
-          "eu-west-2" : { },
-          "sa-east-1" : { },
-          "us-east-1" : { },
-          "us-east-2" : { },
-          "us-west-1" : { },
-          "us-west-2" : { }
-        }
-      }
-    }
-  }, {
-    "defaults" : {
-      "hostname" : "{service}.{region}.{dnsSuffix}",
-      "protocols" : [ "https" ],
-      "signatureVersions" : [ "v4" ]
-    },
-    "dnsSuffix" : "amazonaws.com.cn",
-    "partition" : "aws-cn",
-    "partitionName" : "AWS China",
-    "regionRegex" : "^cn\\-\\w+\\-\\d+$",
-    "regions" : {
-      "cn-north-1" : {
-        "description" : "China (Beijing)"
-      },
-      "cn-northwest-1" : {
-        "description" : "China (Ningxia)"
-      }
-    },
-    "services" : {
-      "apigateway" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "application-autoscaling" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "application-autoscaling"
-          },
-          "hostname" : "autoscaling.{region}.amazonaws.com",
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "autoscaling" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "cloudformation" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "cloudtrail" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "codedeploy" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "cognito-identity" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "config" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "directconnect" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "dynamodb" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "ec2" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "ecr" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "ecs" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "elasticache" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "elasticbeanstalk" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "elasticloadbalancing" : {
-        "defaults" : {
-          "protocols" : [ "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "elasticmapreduce" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "es" : {
-        "endpoints" : {
-          "cn-northwest-1" : { }
-        }
-      },
-      "events" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "glacier" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "iam" : {
-        "endpoints" : {
-          "aws-cn-global" : {
-            "credentialScope" : {
-              "region" : "cn-north-1"
-            },
-            "hostname" : "iam.cn-north-1.amazonaws.com.cn"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-cn-global"
-      },
-      "iot" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "execute-api"
-          }
-        },
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "kinesis" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "lambda" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "logs" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "monitoring" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "rds" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "redshift" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "s3" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ],
-          "signatureVersions" : [ "s3v4" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "sms" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "snowball" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "sns" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "sqs" : {
-        "defaults" : {
-          "protocols" : [ "http", "https" ],
-          "sslCommonName" : "{region}.queue.{dnsSuffix}"
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "ssm" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "storagegateway" : {
-        "endpoints" : {
-          "cn-north-1" : { }
-        }
-      },
-      "streams.dynamodb" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "dynamodb"
-          },
-          "protocols" : [ "http", "https" ]
-        },
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "sts" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "swf" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      },
-      "tagging" : {
-        "endpoints" : {
-          "cn-north-1" : { },
-          "cn-northwest-1" : { }
-        }
-      }
-    }
-  }, {
-    "defaults" : {
-      "hostname" : "{service}.{region}.{dnsSuffix}",
-      "protocols" : [ "https" ],
-      "signatureVersions" : [ "v4" ]
-    },
-    "dnsSuffix" : "amazonaws.com",
-    "partition" : "aws-us-gov",
-    "partitionName" : "AWS GovCloud (US)",
-    "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$",
-    "regions" : {
-      "us-gov-west-1" : {
-        "description" : "AWS GovCloud (US)"
-      }
-    },
-    "services" : {
-      "acm" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "apigateway" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "autoscaling" : {
-        "endpoints" : {
-          "us-gov-west-1" : {
-            "protocols" : [ "http", "https" ]
-          }
-        }
-      },
-      "cloudformation" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "cloudhsm" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "cloudtrail" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "codedeploy" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "config" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "directconnect" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "dms" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "dynamodb" : {
-        "endpoints" : {
-          "us-gov-west-1" : { },
-          "us-gov-west-1-fips" : {
-            "credentialScope" : {
-              "region" : "us-gov-west-1"
-            },
-            "hostname" : "dynamodb.us-gov-west-1.amazonaws.com"
-          }
-        }
-      },
-      "ec2" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "ecr" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "ecs" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "elasticache" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "elasticbeanstalk" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "elasticloadbalancing" : {
-        "endpoints" : {
-          "us-gov-west-1" : {
-            "protocols" : [ "http", "https" ]
-          }
-        }
-      },
-      "elasticmapreduce" : {
-        "endpoints" : {
-          "us-gov-west-1" : {
-            "protocols" : [ "http", "https" ]
-          }
-        }
-      },
-      "es" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "events" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "glacier" : {
-        "endpoints" : {
-          "us-gov-west-1" : {
-            "protocols" : [ "http", "https" ]
-          }
-        }
-      },
-      "iam" : {
-        "endpoints" : {
-          "aws-us-gov-global" : {
-            "credentialScope" : {
-              "region" : "us-gov-west-1"
-            },
-            "hostname" : "iam.us-gov.amazonaws.com"
-          }
-        },
-        "isRegionalized" : false,
-        "partitionEndpoint" : "aws-us-gov-global"
-      },
-      "kinesis" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "kms" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "lambda" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "logs" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "metering.marketplace" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "aws-marketplace"
-          }
-        },
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "monitoring" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "polly" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "rds" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "redshift" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "rekognition" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "s3" : {
-        "defaults" : {
-          "signatureVersions" : [ "s3", "s3v4" ]
-        },
-        "endpoints" : {
-          "fips-us-gov-west-1" : {
-            "credentialScope" : {
-              "region" : "us-gov-west-1"
-            },
-            "hostname" : "s3-fips-us-gov-west-1.amazonaws.com"
-          },
-          "us-gov-west-1" : {
-            "hostname" : "s3.us-gov-west-1.amazonaws.com",
-            "protocols" : [ "http", "https" ]
-          }
-        }
-      },
-      "sms" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "snowball" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "sns" : {
-        "endpoints" : {
-          "us-gov-west-1" : {
-            "protocols" : [ "http", "https" ]
-          }
-        }
-      },
-      "sqs" : {
-        "endpoints" : {
-          "us-gov-west-1" : {
-            "protocols" : [ "http", "https" ],
-            "sslCommonName" : "{region}.queue.{dnsSuffix}"
-          }
-        }
-      },
-      "ssm" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "streams.dynamodb" : {
-        "defaults" : {
-          "credentialScope" : {
-            "service" : "dynamodb"
-          }
-        },
-        "endpoints" : {
-          "us-gov-west-1" : { },
-          "us-gov-west-1-fips" : {
-            "credentialScope" : {
-              "region" : "us-gov-west-1"
-            },
-            "hostname" : "dynamodb.us-gov-west-1.amazonaws.com"
-          }
-        }
-      },
-      "sts" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "swf" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      },
-      "tagging" : {
-        "endpoints" : {
-          "us-gov-west-1" : { }
-        }
-      }
-    }
-  } ],
-  "version" : 3
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/partitions/model/CredentialScope.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/CredentialScope.java
--- ./src/main/java/com/amazonaws/partitions/model/CredentialScope.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/CredentialScope.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,63 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions.model;
-
-/**
- * credential scope associated with an endpoint.
- */
-public class CredentialScope {
-
-    /**
-     * region string to be used when signing a request for an endpoint.
-     */
-    private String region;
-
-    /**
-     * service name string to be used when signing a request for an endpoint
-     */
-    private String service;
-
-    /**
-     * Returns the region string to be used when signing a request for an
-     * endpoint.
-     */
-    public String getRegion() {
-        return region;
-    }
-
-    /**
-     * Sets the region string to be used when signing a request for an
-     * endpoint.
-     */
-    public void setRegion(String region) {
-        this.region = region;
-    }
-
-    /**
-     * Returns the service name string to be used when signing a request for an
-     * endpoint.
-     */
-    public String getService() {
-        return service;
-    }
-
-    /**
-     * Sets the service name string to be used when signing a request for an
-     * endpoint.
-     */
-    public void setService(String service) {
-        this.service = service;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/model/Endpoint.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Endpoint.java
--- ./src/main/java/com/amazonaws/partitions/model/Endpoint.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Endpoint.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,187 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions.model;
-
-import com.amazonaws.Protocol;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.Set;
-
-/**
- * Endpoint configuration.
- */
-public class Endpoint {
-
-    /**
-     * endpoint string.
-     */
-    private String hostName;
-
-    /**
-     * credential scope for the endpoint.
-     */
-    private CredentialScope credentialScope;
-
-    /**
-     * supported schemes for the endpoint.
-     */
-    private Set<String> protocols;
-
-    /**
-     * supported signature versions of the endpoint.
-     */
-    private Set<String> signatureVersions;
-
-    /**
-     * ssl common name for the endpoint.
-     */
-    private String sslCommonName;
-
-    /**
-     * Merges the given endpoints and returns the merged one.
-     */
-    public static Endpoint merge(Endpoint defaults, Endpoint override) {
-
-        if (defaults == null) {
-            defaults = new Endpoint();
-        }
-
-        if (override == null) {
-            override = new Endpoint();
-        }
-
-        final Endpoint merged = new Endpoint();
-
-        merged.setCredentialScope(override.getCredentialScope() != null
-                ? override.getCredentialScope()
-                : defaults.getCredentialScope());
-
-        merged.setHostName(override.getHostName() != null
-                ? override.getHostName()
-                : defaults.getHostName());
-
-        merged.setSslCommonName(override.getSslCommonName() != null
-                ? override.getSslCommonName()
-                : defaults.getSslCommonName());
-
-        merged.setProtocols(override.getProtocols() != null
-                ? override.getProtocols()
-                : defaults.getProtocols());
-
-        merged.setSignatureVersions(override.getSignatureVersions() != null
-                ? override.getSignatureVersions()
-                : defaults.getSignatureVersions()
-        );
-
-        return merged;
-
-    }
-
-    /**
-     * returns the endpoint string.
-     */
-    public String getHostName() {
-        return hostName;
-    }
-
-    /**
-     * sets the endpoint string.
-     */
-    @JsonProperty(value = "hostname")
-    public void setHostName(String hostName) {
-        this.hostName = hostName;
-    }
-
-    /**
-     * returns credential scope for the endpoint.
-     */
-    public CredentialScope getCredentialScope() {
-        return credentialScope;
-    }
-
-    /**
-     * sets the credential scope for the endpoint.
-     */
-    @JsonProperty(value = "credentialScope")
-    public void setCredentialScope(CredentialScope credentialScope) {
-        this.credentialScope = credentialScope;
-    }
-
-    /**
-     * returns the supported schemes for the endpoint.
-     */
-    public Set<String> getProtocols() {
-        return protocols;
-    }
-
-    /**
-     * sets the supported schemes for the endpoint.
-     */
-    @JsonProperty(value = "protocols")
-    public void setProtocols(Set<String> protocols) {
-        this.protocols = protocols;
-    }
-
-    /**
-     * returns the supported signature versions of the endpoint.
-     */
-    public Set<String> getSignatureVersions() {
-        return signatureVersions;
-    }
-
-    /**
-     * returns the supported signature versions of the endpoint.
-     */
-    @JsonProperty(value = "signatureVersions")
-    public void setSignatureVersions(Set<String> signatureVersions) {
-        this.signatureVersions = signatureVersions;
-    }
-
-    /**
-     * returns the ssl common name for the endpoint.
-     */
-    public String getSslCommonName() {
-        return sslCommonName;
-    }
-
-    /**
-     * sets the ssl common name for the endpoint.
-     */
-    @JsonProperty(value = "sslCommonName")
-    public void setSslCommonName(String sslCommonName) {
-        this.sslCommonName = sslCommonName;
-    }
-
-    /**
-     * A convienient methods that returns true if the endpoint support HTTPS
-     * scheme. Returns false otherwise.
-     */
-    public boolean hasHttpsSupport() {
-        return isProtocolSupported(Protocol.HTTPS);
-    }
-
-    /**
-     * A convienient methods that returns true if the endpoint support HTTP
-     * scheme. Returns false otherwise.
-     */
-    public boolean hasHttpSupport() {
-        return isProtocolSupported(Protocol.HTTP);
-    }
-
-    private boolean isProtocolSupported(Protocol protocol) {
-        return protocols != null && protocols.contains(protocol.toString());
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/model/Partition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Partition.java
--- ./src/main/java/com/amazonaws/partitions/model/Partition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Partition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,180 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions.model;
-
-import com.amazonaws.util.ValidationUtils;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * This class models a AWS partition and contains all metadata about it.
- */
-public class Partition {
-
-    /**
-     * The name of the partition.
-     */
-    private final String partition;
-
-    /**
-     * Supported regions.
-     */
-    private final Map<String, Region> regions;
-
-    /**
-     * Supported services;
-     */
-    private final Map<String, Service> services;
-
-    /**
-     * description of the partition.
-     */
-    private String partitionName;
-
-    /**
-     * dns suffix for the endpoints in the partition.
-     */
-    private String dnsSuffix;
-
-    /**
-     * region name regex for regions in the partition.
-     */
-    private String regionRegex;
-
-    /**
-     * default endpoint configuration.
-     */
-    private Endpoint defaults;
-
-    public Partition(@JsonProperty(value = "partition") String partition,
-                     @JsonProperty(value = "regions") Map<String, Region>
-                             regions,
-                     @JsonProperty(value = "services") Map<String,
-                             Service> services) {
-        this.partition = ValidationUtils.assertNotNull(partition, "Partition");
-        this.regions = regions;
-        this.services = services;
-    }
-
-    /**
-     * Returns the name of the partition.
-     */
-    public String getPartition() {
-        return partition;
-    }
-
-    /**
-     * Returns the description of the partition.
-     */
-    public String getPartitionName() {
-        return partitionName;
-    }
-
-    /**
-     * Sets the description of the partition.
-     */
-    public void setPartitionName(String partitionName) {
-        this.partitionName = partitionName;
-    }
-
-    /**
-     * Returns the dns suffix of the partition.
-     */
-    public String getDnsSuffix() {
-        return dnsSuffix;
-    }
-
-    /**
-     * Sets the dns suffix of the partition.
-     */
-    public void setDnsSuffix(String dnsSuffix) {
-        this.dnsSuffix = dnsSuffix;
-    }
-
-    /**
-     * Returns the regex for the regions in the partition.
-     */
-    public String getRegionRegex() {
-        return regionRegex;
-    }
-
-    /**
-     * Sets the regex for the regions in the partition.
-     */
-    public void setRegionRegex(String regionRegex) {
-        this.regionRegex = regionRegex;
-    }
-
-    /**
-     * Returns the default endpoint configuration of the partition.
-     */
-    public Endpoint getDefaults() {
-        return defaults;
-    }
-
-    /**
-     * Sets the default endpoint configuration of the partition.
-     */
-    public void setDefaults(Endpoint defaults) {
-        this.defaults = defaults;
-    }
-
-    /**
-     * Returns the set of regions associated with the partition.
-     */
-    public Map<String, Region> getRegions() {
-        return regions;
-    }
-
-    /**
-     * Returns the set of services supported by the partition.
-     */
-    public Map<String, Service> getServices() {
-        return services;
-    }
-
-    /**
-     * Returns true if the region is explicitly configured in the partition
-     * or if the region matches the {@link #regionRegex} of the partition.
-     */
-    public boolean hasRegion(String region) {
-        return regions.containsKey(region) || matchesRegionRegex(region) || hasServiceEndpoint
-                (region);
-    }
-
-    private boolean matchesRegionRegex(String region) {
-        final Pattern p = Pattern.compile(regionRegex);
-        return p.matcher(region).matches();
-    }
-
-    /**
-     * returns true if any of the services in the partition has a custom endpoint
-     * like s3 having s3-external-1.
-     * TODO Remove this support as part of next major version.
-     * @Deprecated use the {@link com.amazonaws.AmazonWebServiceClient#setEndpoint(String)} method
-     * for custom endpoints.
-     */
-    @Deprecated
-    private boolean hasServiceEndpoint(String endpoint) {
-        for(Service s : services.values()) {
-            if (s.getEndpoints().containsKey(endpoint)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/model/Partitions.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Partitions.java
--- ./src/main/java/com/amazonaws/partitions/model/Partitions.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Partitions.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/**
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * <p/>
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
- * the License. A copy of the License is located at
- * <p/>
- * http://aws.amazon.com/apache2.0
- * <p/>
- * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- */
-package com.amazonaws.partitions.model;
-
-import com.amazonaws.util.ValidationUtils;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.List;
-
-/**
- * Metadata of all partitions.
- */
-public class Partitions {
-
-    /**
-     * the version of json schema for the partition metadata.
-     */
-    private final String version;
-
-    /**
-     * list of partitions.
-     */
-    private final List<Partition> partitions;
-
-    public Partitions(@JsonProperty(value = "version") String version, @JsonProperty(value = "partitions") List<Partition> partitions) {
-        this.version = ValidationUtils.assertNotNull(version, "version");
-        this.partitions = ValidationUtils.assertNotNull(partitions, "version");
-    }
-
-    /**
-     * returns the version of the json schema for the partition metadata document.
-     */
-    public String getVersion() {
-        return version;
-    }
-
-    /**
-     * returns the list of all partitions loaded from the partition metadata document.
-     */
-    public List<Partition> getPartitions() {
-        return partitions;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/model/Region.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Region.java
--- ./src/main/java/com/amazonaws/partitions/model/Region.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Region.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions.model;
-
-import com.amazonaws.util.ValidationUtils;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * Metadata about a region in partition.
- */
-public class Region {
-
-    /**
-     * description of the region.
-     */
-    private final String description;
-
-    public Region(@JsonProperty(value = "description") String description) {
-        this.description = ValidationUtils.assertNotNull(description, "Region description");;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/model/Service.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Service.java
--- ./src/main/java/com/amazonaws/partitions/model/Service.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/model/Service.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,117 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Endpoint configuration for a service in a partition.
- */
-public class Service {
-
-    /**
-     * endpoint configuration for every region in a partition.
-     */
-    private final Map<String, Endpoint> endpoints;
-
-    /**
-     * default endpoint configuration for a service across all regions in the
-     * partition
-     */
-    private Endpoint defaults;
-
-    /**
-     * the region name if the service is enabled partition wide.
-     */
-    private String partitionEndpoint;
-
-    /**
-     * Returns true if the service is regionalized.
-     */
-    private boolean isRegionalized;
-
-    public Service(@JsonProperty(value = "endpoints") Map<String,
-            Endpoint> endpoints) {
-        // Technically the endpoints member should never be null if the
-        // endpoints file is properly formed, but this is currently not always
-        // true. See TRE-739 for details
-        this.endpoints = endpoints == null ? Collections.<String, Endpoint>emptyMap() : endpoints;
-    }
-
-    /**
-     * Returns the endpoints configuration for all regions in a partition
-     * that service supports.
-     */
-    public Map<String, Endpoint> getEndpoints() {
-        return endpoints;
-    }
-
-    /**
-     * returns the default endpoints configuration for all regions in a
-     * partition.
-     */
-    public Endpoint getDefaults() {
-        return defaults;
-    }
-
-    /**
-     * Sets the default endpoints configuration for all regions in a
-     * partition.
-     */
-    public void setDefaults(Endpoint defaults) {
-        this.defaults = defaults;
-    }
-
-    /**
-     * returns the region name if the service is enabled partition wide.
-     */
-    public String getPartitionEndpoint() {
-        return partitionEndpoint;
-    }
-
-    /**
-     * sets the region name if the service is enabled partition wide.
-     */
-    @JsonProperty(value = "partitionEndpoint")
-    public void setPartitionEndpoint(String partitionEndpoint) {
-        this.partitionEndpoint = partitionEndpoint;
-    }
-
-    /**
-     * returns true if the service is regionalized.
-     */
-    public boolean isRegionalized() {
-        return isRegionalized;
-    }
-
-    /**
-     * sets the regionalized property for a service..
-     */
-    @JsonProperty(value = "isRegionalized")
-    public void setRegionalized(boolean regionalized) {
-        isRegionalized = regionalized;
-    }
-
-    /**
-     * A convienient method that returns true if a service has a partition
-     * wide endpoint available.
-     */
-    public boolean isPartitionWideEndpointAvailable() {
-        return this.partitionEndpoint != null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/PartitionMetadataProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/PartitionMetadataProvider.java
--- ./src/main/java/com/amazonaws/partitions/PartitionMetadataProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/PartitionMetadataProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,111 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.partitions.model.Partition;
-import com.amazonaws.regions.AbstractRegionMetadataProvider;
-import com.amazonaws.regions.Region;
-import com.amazonaws.util.ValidationUtils;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Region metadata provider based on partitions.
- */
-@SdkInternalApi
-public class PartitionMetadataProvider extends AbstractRegionMetadataProvider {
-
-    private final Map<String, Partition> partitionMap = new HashMap<String,
-            Partition>();
-
-    private final Map<String, Region> regionCache = new ConcurrentHashMap<String, Region>();
-
-    public PartitionMetadataProvider(List<Partition> partitions) {
-        ValidationUtils.assertNotNull(partitions, "partitions");
-
-        for (Partition p : partitions) {
-            partitionMap.put(p.getPartition(), p);
-        }
-    }
-
-    @Override
-    public List<Region> getRegions() {
-        final List<Region> regions = new ArrayList<Region>();
-
-        for (Partition p : partitionMap.values()) {
-            for (Map.Entry<String, com.amazonaws.partitions.model.Region>
-                    entry : p.getRegions().entrySet()) {
-                regions.add(new Region(new PartitionRegionImpl(entry.getKey(),
-                        p)));
-            }
-        }
-        return Collections.unmodifiableList(regions);
-    }
-
-    @Override
-    public Region getRegion(String regionName) {
-
-        if (regionName == null) return null;
-
-        final Region regionFromCache = getRegionFromCache(regionName);
-
-        if (regionFromCache != null) {
-            return regionFromCache;
-        }
-
-        return createNewRegion(regionName);
-    }
-
-    private Region createNewRegion(String regionName) {
-        for (Partition p : partitionMap.values()) {
-            if (p.hasRegion(regionName)) {
-                return cacheRegion(new PartitionRegionImpl(regionName, p));
-            }
-        }
-        return null;
-    }
-
-    private Region getRegionFromCache(String regionName) {
-        return regionCache.get(regionName);
-    }
-
-    private Region cacheRegion(PartitionRegionImpl regionImpl) {
-        final Region region = new Region(regionImpl);
-
-        regionCache.put(region.getName(), region);
-
-        return region;
-    }
-
-    @Override
-    public List<Region> getRegionsForService(String serviceName) {
-        final List<Region> allRegions = getRegions();
-        final List<Region> serviceSupportedRegions = new ArrayList<Region>();
-
-        for (Region r : allRegions) {
-            if (r.isServiceSupported(serviceName)) {
-                serviceSupportedRegions.add(r);
-            }
-        }
-        return serviceSupportedRegions;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/PartitionRegionImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/PartitionRegionImpl.java
--- ./src/main/java/com/amazonaws/partitions/PartitionRegionImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/PartitionRegionImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,219 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions;
-
-import com.amazonaws.partitions.model.Endpoint;
-import com.amazonaws.partitions.model.Partition;
-import com.amazonaws.partitions.model.Service;
-import com.amazonaws.regions.RegionImpl;
-import com.amazonaws.util.ValidationUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A region implementation backed by the partition.
- */
-public class PartitionRegionImpl implements RegionImpl {
-
-    private static final String SERVICE = "{service}";
-    private static final String REGION = "{region}";
-    private static final String DNS_SUFFIX = "{dnsSuffix}";
-
-    /**
-     * partition where the region is present.
-     */
-    private final Partition partition;
-
-    /**
-     * the name of the region.
-     */
-    private final String region;
-
-    /**
-     * endpoint cache for a service.
-     */
-    private final Map<String, Endpoint> endpointCache = new ConcurrentHashMap<String,
-                Endpoint>();
-
-    public PartitionRegionImpl(String region, Partition p) {
-        this.partition = ValidationUtils.assertNotNull(p, "partition");
-        this.region = ValidationUtils.assertNotNull(region, "region");
-    }
-
-    @Override
-    public String getName() {
-        return region;
-    }
-
-    @Override
-    public String getDomain() {
-        return partition.getDnsSuffix();
-    }
-
-    @Override
-    public String getPartition() {
-        return partition.getPartition();
-    }
-
-    /**
-     * Returns the endpoint for the given service.
-     * If the region is not present under service configuration; but matches
-     * the region regex, then this system tries to guess the endpoint and
-     * returns it.
-     */
-    @Override
-    public String getServiceEndpoint(String serviceName) {
-        return getEndpointString(serviceName, getEndpoint(serviceName));
-    }
-
-    /**
-     * Returns the endpoint configuration for a given service.
-     */
-    private Endpoint getEndpoint(String serviceName) {
-        Endpoint cachedEndpoint = endpointCache.get(serviceName);
-
-        if (cachedEndpoint == null) {
-            cachedEndpoint = computeEndpoint(serviceName);
-            if (cachedEndpoint == null) {
-                return null;
-            }
-        }
-
-        endpointCache.put(serviceName, cachedEndpoint);
-        return cachedEndpoint;
-    }
-
-    private Endpoint computeEndpoint(String serviceName) {
-
-        Service service = partition.getServices().get(serviceName);
-
-
-        if (service != null) {
-            if (service.getEndpoints().containsKey(region)) {
-
-                Endpoint merged = Endpoint.merge(
-                        partition.getDefaults(),
-                        Endpoint.merge(service.getDefaults(),
-                                service.getEndpoints().get(region)));
-
-                return merged;
-
-            } else if (service.isPartitionWideEndpointAvailable() && !service
-                        .isRegionalized()) {
-                // partition doesn't have any information about a service.
-
-                Endpoint merged = Endpoint.merge(
-                        partition.getDefaults(),
-                        Endpoint.merge(service.getDefaults(),
-                                service.getEndpoints().get(
-                                        service.getPartitionEndpoint())));
-
-                return merged;
-
-            } else {
-                if (partition.getDefaults() != null
-                        && partition.getDefaults().getHostName() != null) {
-                    return partition.getDefaults();
-                }
-            }
-        }
-        return null;
-    }
-
-    private String getEndpointString(String serviceName, Endpoint endpoint) {
-        return endpoint == null
-                ? null
-                : endpoint.getHostName()
-                .replace(SERVICE, serviceName)
-                .replace(REGION, region)
-                .replace(DNS_SUFFIX, partition.getDnsSuffix());
-    }
-
-    /**
-     * Returns true if the service is explicitly enabled for a region or a
-     * service is partition wide enabled. Returns false otherwise.
-     * <p/>
-     * For new regions that match the partition's region regex, if the
-     * service is enabled partition wide then this method will return true.
-     */
-    @Override
-    public boolean isServiceSupported(String serviceName) {
-        return isServiceSupportedInRegion(serviceName) || isServicePartitionWide
-                (serviceName);
-    }
-
-    /**
-     * This method returns true only if the metadata for the service contains the given
-     * region in the list of supported regions.
-     */
-    private boolean isServiceSupportedInRegion(String serviceName) {
-        return partition.getServices().get(serviceName) != null
-                && partition.getServices().get(serviceName).getEndpoints()
-                .containsKey(region);
-    }
-
-    private boolean isServicePartitionWide(String serviceName) {
-        return partition.getServices().get(serviceName) != null
-                && partition.getServices().get(serviceName)
-                .getPartitionEndpoint() != null;
-    }
-
-    /**
-     * Returns true if the service is explicitly enabled for https in this
-     * region or a service is partition wide enabled. Returns false otherwise.
-     * <p/>
-     * For new regions that match the partition's region regex, if the
-     * service is enabled partition wide then this method will return true.
-     */
-    @Override
-    public boolean hasHttpsEndpoint(String serviceName) {
-
-        if (!isServiceSupported(serviceName)) return false;
-
-        return getEndpoint(serviceName).hasHttpsSupport();
-
-    }
-
-    /**
-     * Returns true if the service is explicitly enabled for http in this
-     * region or a service is partition wide enabled. Returns false otherwise.
-     * <p/>
-     * For new regions that match the partition's region regex, if the
-     * service is enabled partition wide then this method will return true.
-     */
-    @Override
-    public boolean hasHttpEndpoint(String serviceName) {
-        if (!isServiceSupported(serviceName)) return false;
-
-        return getEndpoint(serviceName).hasHttpSupport();
-    }
-
-    @Override
-    public Collection<String> getAvailableEndpoints() {
-        final List<String> endpoints = new ArrayList<String>();
-        for (String service : partition.getServices().keySet()) {
-            if (isServiceSupported(service)) {
-                endpoints.add(getServiceEndpoint(service));
-            }
-        }
-        return Collections.unmodifiableCollection(endpoints);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/partitions/PartitionsLoader.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/PartitionsLoader.java
--- ./src/main/java/com/amazonaws/partitions/PartitionsLoader.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/partitions/PartitionsLoader.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,101 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.partitions;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.partitions.model.Partitions;
-import com.amazonaws.regions.RegionMetadata;
-import com.amazonaws.util.IOUtils;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.MapperFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * Loads all the partition files into memory.
- */
-@SdkInternalApi
-public class PartitionsLoader {
-
-    /**
-     * class path from where all partition files are loaded.
-     */
-    public static final String PARTITIONS_RESOURCE_PATH =
-            "com/amazonaws/partitions/endpoints.json";
-
-    /**
-     * override class path from where all partition files are loaded.
-     */
-    public static final String PARTITIONS_OVERRIDE_RESOURCE_PATH =
-            "com/amazonaws/partitions/override/endpoints.json";
-
-    /**
-     * Jackson object mapper that is used for parsing the partition files.
-     */
-    private static final ObjectMapper mapper = new ObjectMapper()
-            .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
-            .disable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS)
-            .enable(JsonParser.Feature.ALLOW_COMMENTS)
-            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-
-    /**
-     * classloader to to be used for loading the partitions.
-     */
-    private final ClassLoader classLoader;
-
-    public PartitionsLoader() {
-        this.classLoader = PartitionsLoader.class.getClassLoader();
-    }
-
-    /**
-     * Loads the partition files from the {@link #PARTITIONS_OVERRIDE_RESOURCE_PATH}. If no files are present, then
-     * loads the partition files from the {@link #PARTITIONS_RESOURCE_PATH}
-     * <p/>
-     * Builds the {@link RegionMetadata} from the partition files.
-     */
-    public PartitionMetadataProvider build() {
-
-        InputStream stream = classLoader
-                .getResourceAsStream(PARTITIONS_OVERRIDE_RESOURCE_PATH);
-
-        if (stream != null) {
-            return new PartitionMetadataProvider(loadPartitionFromStream(stream, PARTITIONS_OVERRIDE_RESOURCE_PATH).getPartitions());
-        } else {
-            stream = classLoader.getResourceAsStream(PARTITIONS_RESOURCE_PATH);
-            if (stream == null) {
-                throw new SdkClientException("Unable to load partition metadata from " + PARTITIONS_RESOURCE_PATH);
-            }
-            return new PartitionMetadataProvider(loadPartitionFromStream(stream, PARTITIONS_RESOURCE_PATH).getPartitions());
-        }
-    }
-
-    private Partitions loadPartitionFromStream(InputStream stream, String location) {
-
-        try {
-
-            return mapper.readValue(stream, Partitions.class);
-
-        } catch (IOException e) {
-            throw new SdkClientException("Error while loading partitions " +
-                    "file from " + location, e);
-        } finally {
-            IOUtils.closeQuietly(stream, null);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/PredefinedClientConfigurations.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/PredefinedClientConfigurations.java
--- ./src/main/java/com/amazonaws/PredefinedClientConfigurations.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/PredefinedClientConfigurations.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,48 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.retry.PredefinedRetryPolicies;
-
-/**
- * Static factory methods for the default {@link ClientConfiguration} for a service. These defaults
- * are used unless a different {@link ClientConfiguration} is explicitly provided in the constructor
- * of the service client
- */
-public class PredefinedClientConfigurations {
-
-    /**
-     * Factory method for default {@link ClientConfiguration} for all services unless otherwise
-     * specified
-     */
-    public static ClientConfiguration defaultConfig() {
-        return new ClientConfiguration();
-    }
-
-    /**
-     * Factory method for DynamoDB's default {@link ClientConfiguration}
-     */
-    public static ClientConfiguration dynamoDefault() {
-        return new ClientConfiguration().withRetryPolicy(PredefinedRetryPolicies.DYNAMODB_DEFAULT);
-    }
-
-    /**
-     * Factory method for Simple Workflow's default {@link ClientConfiguration}
-     */
-    public static ClientConfiguration swfDefault() {
-        return new ClientConfiguration().withMaxConnections(1000).withSocketTimeout(90000);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/DefaultMarshallingType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/DefaultMarshallingType.java
--- ./src/main/java/com/amazonaws/protocol/DefaultMarshallingType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/DefaultMarshallingType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,33 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.protocol;
-
-/**
- * A base implementation for {@link MarshallingType}s that are the default marshallers for their respective types. This will
- * return "true" for {@link #isDefaultMarshallerForType(Class)} if the provided class is a subclass of this class's type.
- */
-final class DefaultMarshallingType<T> implements MarshallingType<T> {
-    private final Class<T> type;
-
-    protected DefaultMarshallingType(Class<T> type) {
-        this.type = type;
-    }
-
-    @Override
-    public boolean isDefaultMarshallerForType(Class<?> type) {
-        return this.type.isAssignableFrom(type);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/DefaultValueSupplier.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/DefaultValueSupplier.java
--- ./src/main/java/com/amazonaws/protocol/DefaultValueSupplier.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/DefaultValueSupplier.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,33 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Interface to provide a default value for a null member during marshalling. Currently used for
- * members that have the idempotency trait applied and for Glacier's account ID member (which defaults to '-' indicating
- * the current account).
- *
- * @param <T> Type of the member to provide the default value for.
- */
-@SdkProtectedApi
-public interface DefaultValueSupplier<T> {
-
-    /**
-     * @return The default value to use if the value is null.
-     */
-    T get();
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/HeaderMarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/HeaderMarshallers.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/HeaderMarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/HeaderMarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,58 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import java.util.Date;
-
-@SdkInternalApi
-public class HeaderMarshallers {
-
-    public static final JsonMarshaller<String> STRING = new SimpleHeaderMarshaller<String>(
-            ValueToStringConverters.FROM_STRING);
-
-    public static final JsonMarshaller<String> JSON_VALUE = new SimpleHeaderMarshaller<String>(
-            ValueToStringConverters.FROM_JSON_VALUE_HEADER);
-
-    public static final JsonMarshaller<Integer> INTEGER = new SimpleHeaderMarshaller<Integer>(
-            ValueToStringConverters.FROM_INTEGER);
-
-    public static final JsonMarshaller<Long> LONG = new SimpleHeaderMarshaller<Long>(ValueToStringConverters.FROM_LONG);
-
-    public static final JsonMarshaller<Double> DOUBLE = new SimpleHeaderMarshaller<Double>(
-            ValueToStringConverters.FROM_DOUBLE);
-
-    public static final JsonMarshaller<Float> FLOAT = new SimpleHeaderMarshaller<Float>(ValueToStringConverters.FROM_FLOAT);
-
-    public static final JsonMarshaller<Boolean> BOOLEAN = new SimpleHeaderMarshaller<Boolean>(
-            ValueToStringConverters.FROM_BOOLEAN);
-
-    public static final JsonMarshaller<Date> DATE = new SimpleHeaderMarshaller<Date>(ValueToStringConverters.FROM_DATE);
-
-    private static class SimpleHeaderMarshaller<T> implements JsonMarshaller<T> {
-
-        private final ValueToStringConverters.ValueToString<T> converter;
-
-        private SimpleHeaderMarshaller(ValueToStringConverters.ValueToString<T> converter) {
-            this.converter = converter;
-        }
-
-        @Override
-        public void marshall(T val, JsonMarshallerContext context, String paramName) {
-            context.request().addHeader(paramName, converter.convert(val));
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/JsonMarshallerContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/JsonMarshallerContext.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/JsonMarshallerContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/JsonMarshallerContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,139 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.Request;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.protocol.json.StructuredJsonGenerator;
-import com.amazonaws.protocol.MarshallLocation;
-import com.amazonaws.protocol.ProtocolMarshaller;
-
-/**
- * Dependencies needed by implemenatations of {@link JsonMarshaller}.
- */
-@SdkInternalApi
-public class JsonMarshallerContext {
-
-    private final StructuredJsonGenerator jsonGenerator;
-    private final JsonProtocolMarshaller protocolHandler;
-    private final MarshallerRegistry marshallerRegistry;
-    private final Request<?> request;
-
-    private JsonMarshallerContext(Builder builder) {
-        this.jsonGenerator = builder.jsonGenerator;
-        this.protocolHandler = builder.protocolHandler;
-        this.marshallerRegistry = builder.marshallerRegistry;
-        this.request = builder.request;
-    }
-
-    /**
-     * @return StructuredJsonGenerator used to produce the JSON document for a request.
-     */
-    public StructuredJsonGenerator jsonGenerator() {
-        return jsonGenerator;
-    }
-
-    /**
-     * @return Implementation of {@link ProtocolMarshaller} that can be used to call back out to marshall structured data (i.e.
-     * lists of objects).
-     */
-    public ProtocolMarshaller protocolHandler() {
-        return protocolHandler;
-    }
-
-    /**
-     * @return Marshaller registry to obtain marshaller implementations for nested types (i.e. lists of objects or maps of string
-     * to string).
-     */
-    public MarshallerRegistry marshallerRegistry() {
-        return marshallerRegistry;
-    }
-
-    /**
-     * @return Mutable {@link Request} object that can be used to add headers, query params, modify request URI, etc.
-     */
-    public Request<?> request() {
-        return request;
-    }
-
-    /**
-     * Convenience method to marshall a nested object (may be simple or structured) at the given location.
-     *
-     * @param marshallLocation Current {@link MarshallLocation}
-     * @param val              Value to marshall.
-     */
-    public void marshall(MarshallLocation marshallLocation, Object val) {
-        marshallerRegistry().getMarshaller(marshallLocation, val).marshall(val, this, null);
-    }
-
-    /**
-     * Convenience method to marshall a nested object (may be simple or structured) at the given location.
-     *
-     * @param marshallLocation Current {@link MarshallLocation}
-     * @param val              Value to marshall.
-     * @param paramName        Name of parameter to marshall.
-     */
-    public void marshall(MarshallLocation marshallLocation, Object val, String paramName) {
-        marshallerRegistry().getMarshaller(marshallLocation, val).marshall(val, this, paramName);
-    }
-
-    /**
-     * @return Builder instance to construct a {@link JsonMarshallerContext}.
-     */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Builder for a {@link JsonMarshallerContext}.
-     */
-    public static final class Builder {
-
-        private StructuredJsonGenerator jsonGenerator;
-        private JsonProtocolMarshaller protocolHandler;
-        private MarshallerRegistry marshallerRegistry;
-        private Request<?> request;
-
-        private Builder() {
-        }
-
-        public Builder jsonGenerator(StructuredJsonGenerator jsonGenerator) {
-            this.jsonGenerator = jsonGenerator;
-            return this;
-        }
-
-        public Builder protocolHandler(JsonProtocolMarshaller protocolHandler) {
-            this.protocolHandler = protocolHandler;
-            return this;
-        }
-
-        public Builder marshallerRegistry(MarshallerRegistry marshallerRegistry) {
-            this.marshallerRegistry = marshallerRegistry;
-            return this;
-        }
-
-        public Builder request(Request<?> request) {
-            this.request = request;
-            return this;
-        }
-
-        /**
-         * @return An immutable {@link JsonMarshallerContext} object.
-         */
-        public JsonMarshallerContext build() {
-            return new JsonMarshallerContext(this);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/JsonMarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/JsonMarshaller.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/JsonMarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/JsonMarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Interface to marshall data according to the JSON protocol specification.
- *
- * @param <T> Type to marshall.
- */
-@SdkInternalApi
-public interface JsonMarshaller<T> {
-
-    JsonMarshaller<Void> NULL = new JsonMarshaller<Void>() {
-        @Override
-        public void marshall(Void val, JsonMarshallerContext context, String paramName) {
-        }
-    };
-
-    /**
-     * Marshall the data into the request.
-     *
-     * @param val       Data to marshall (may be null).
-     * @param context   Dependencies needed for marshalling.
-     * @param paramName Optional param/field name. May be null in certain situations.
-     */
-    void marshall(T val, JsonMarshallerContext context, String paramName);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/JsonProtocolMarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/JsonProtocolMarshaller.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/JsonProtocolMarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/JsonProtocolMarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,200 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is divalibuted
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.DefaultRequest;
-import com.amazonaws.Request;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.protocol.MarshallingInfo;
-import com.amazonaws.protocol.MarshallingType;
-import com.amazonaws.protocol.OperationInfo;
-import com.amazonaws.protocol.ProtocolMarshaller;
-import com.amazonaws.protocol.ProtocolRequestMarshaller;
-import com.amazonaws.protocol.json.StructuredJsonGenerator;
-import com.amazonaws.util.BinaryUtils;
-import com.amazonaws.util.UriResourcePathUtils;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-/**
- * Implementation of {@link ProtocolMarshaller} for JSON based services. This includes JSON-RPC and REST-JSON.
- *
- * @param <OrigRequest> Type of the original request object.
- */
-@SdkInternalApi
-public class JsonProtocolMarshaller<OrigRequest> implements ProtocolRequestMarshaller<OrigRequest> {
-
-    private static final MarshallerRegistry DEFAULT_MARSHALLER_REGISTRY = createDefaultMarshallerRegistry();
-
-    private final StructuredJsonGenerator jsonGenerator;
-    private final Request<OrigRequest> request;
-    private final String contentType;
-    private final boolean hasExplicitPayloadMember;
-
-    private final JsonMarshallerContext marshallerContext;
-    private final MarshallerRegistry marshallerRegistry;
-
-    public JsonProtocolMarshaller(StructuredJsonGenerator jsonGenerator,
-                                  String contentType,
-                                  OperationInfo operationInfo,
-                                  OrigRequest originalRequest,
-                                  MarshallerRegistry.Builder marshallerRegistryOverrides) {
-        this.jsonGenerator = jsonGenerator;
-        this.contentType = contentType;
-        this.hasExplicitPayloadMember = operationInfo.hasExplicitPayloadMember();
-        this.request = fillBasicRequestParams(operationInfo, originalRequest);
-        this.marshallerRegistry = DEFAULT_MARSHALLER_REGISTRY.merge(marshallerRegistryOverrides);
-        this.marshallerContext = JsonMarshallerContext.builder()
-                                                      .jsonGenerator(jsonGenerator)
-                                                      .marshallerRegistry(marshallerRegistry)
-                                                      .protocolHandler(this)
-                                                      .request(request)
-                                                      .build();
-    }
-
-    private Request<OrigRequest> fillBasicRequestParams(OperationInfo operationInfo, OrigRequest originalRequest) {
-        Request<OrigRequest> request = createRequest(operationInfo, originalRequest);
-        request.setHttpMethod(operationInfo.httpMethodName());
-        request.setResourcePath(UriResourcePathUtils.addStaticQueryParamtersToRequest(request, operationInfo.requestUri()));
-        if (operationInfo.operationIdentifier() != null) {
-            request.addHeader("X-Amz-Target", operationInfo.operationIdentifier());
-        }
-        return request;
-    }
-
-    private DefaultRequest<OrigRequest> createRequest(OperationInfo operationInfo, OrigRequest originalRequest) {
-        if (originalRequest instanceof AmazonWebServiceRequest) {
-            return new DefaultRequest<OrigRequest>((AmazonWebServiceRequest) originalRequest, operationInfo.serviceName());
-        } else {
-            return new DefaultRequest<OrigRequest>(operationInfo.serviceName());
-        }
-    }
-
-    private static MarshallerRegistry createDefaultMarshallerRegistry() {
-        return MarshallerRegistry.builder()
-                                 .payloadMarshaller(MarshallingType.STRING, SimpleTypeJsonMarshallers.STRING)
-                                 .payloadMarshaller(MarshallingType.JSON_VALUE, SimpleTypeJsonMarshallers.STRING)
-                                 .payloadMarshaller(MarshallingType.INTEGER, SimpleTypeJsonMarshallers.INTEGER)
-                                 .payloadMarshaller(MarshallingType.LONG, SimpleTypeJsonMarshallers.LONG)
-                                 .payloadMarshaller(MarshallingType.DOUBLE, SimpleTypeJsonMarshallers.DOUBLE)
-                                 .payloadMarshaller(MarshallingType.FLOAT, SimpleTypeJsonMarshallers.FLOAT)
-                                 .payloadMarshaller(MarshallingType.BIG_DECIMAL, SimpleTypeJsonMarshallers.BIG_DECIMAL)
-                                 .payloadMarshaller(MarshallingType.BOOLEAN, SimpleTypeJsonMarshallers.BOOLEAN)
-                                 .payloadMarshaller(MarshallingType.DATE, SimpleTypeJsonMarshallers.DATE)
-                                 .payloadMarshaller(MarshallingType.BYTE_BUFFER, SimpleTypeJsonMarshallers.BYTE_BUFFER)
-                                 .payloadMarshaller(MarshallingType.STRUCTURED, SimpleTypeJsonMarshallers.STRUCTURED)
-                                 .payloadMarshaller(MarshallingType.LIST, SimpleTypeJsonMarshallers.LIST)
-                                 .payloadMarshaller(MarshallingType.MAP, SimpleTypeJsonMarshallers.MAP)
-                                 .payloadMarshaller(MarshallingType.NULL, SimpleTypeJsonMarshallers.NULL)
-
-                                 .headerMarshaller(MarshallingType.STRING, HeaderMarshallers.STRING)
-                                 .headerMarshaller(MarshallingType.JSON_VALUE, HeaderMarshallers.JSON_VALUE)
-                                 .headerMarshaller(MarshallingType.INTEGER, HeaderMarshallers.INTEGER)
-                                 .headerMarshaller(MarshallingType.LONG, HeaderMarshallers.LONG)
-                                 .headerMarshaller(MarshallingType.DOUBLE, HeaderMarshallers.DOUBLE)
-                                 .headerMarshaller(MarshallingType.FLOAT, HeaderMarshallers.FLOAT)
-                                 .headerMarshaller(MarshallingType.BOOLEAN, HeaderMarshallers.BOOLEAN)
-                                 .headerMarshaller(MarshallingType.DATE, HeaderMarshallers.DATE)
-                                 .headerMarshaller(MarshallingType.NULL, JsonMarshaller.NULL)
-
-                                 .queryParamMarshaller(MarshallingType.STRING, QueryParamMarshallers.STRING)
-                                 .queryParamMarshaller(MarshallingType.INTEGER, QueryParamMarshallers.INTEGER)
-                                 .queryParamMarshaller(MarshallingType.LONG, QueryParamMarshallers.LONG)
-                                 .queryParamMarshaller(MarshallingType.DOUBLE, QueryParamMarshallers.DOUBLE)
-                                 .queryParamMarshaller(MarshallingType.FLOAT, QueryParamMarshallers.FLOAT)
-                                 .queryParamMarshaller(MarshallingType.BOOLEAN, QueryParamMarshallers.BOOLEAN)
-                                 .queryParamMarshaller(MarshallingType.DATE, QueryParamMarshallers.DATE)
-                                 .queryParamMarshaller(MarshallingType.LIST, QueryParamMarshallers.LIST)
-                                 .queryParamMarshaller(MarshallingType.MAP, QueryParamMarshallers.MAP)
-                                 .queryParamMarshaller(MarshallingType.NULL, JsonMarshaller.NULL)
-
-                                 .pathParamMarshaller(MarshallingType.STRING, SimpleTypePathMarshallers.STRING)
-                                 .pathParamMarshaller(MarshallingType.INTEGER, SimpleTypePathMarshallers.INTEGER)
-                                 .pathParamMarshaller(MarshallingType.LONG, SimpleTypePathMarshallers.LONG)
-                                 .pathParamMarshaller(MarshallingType.NULL, SimpleTypePathMarshallers.NULL)
-
-                                 .greedyPathParamMarshaller(MarshallingType.STRING, SimpleTypePathMarshallers.GREEDY_STRING)
-                                 .greedyPathParamMarshaller(MarshallingType.NULL, SimpleTypePathMarshallers.NULL)
-                                 .build();
-    }
-
-    /**
-     * If there is not an explicit payload member then we need to start the implicit JSON request object. All
-     * members bound to the payload will be added as fields to this object.
-     */
-    @Override
-    public void startMarshalling() {
-        if (!hasExplicitPayloadMember) {
-            jsonGenerator.writeStartObject();
-        }
-    }
-
-    @Override
-    public <V> void marshall(V val, MarshallingInfo<V> marshallingInfo) {
-        doMarshall(resolveValue(val, marshallingInfo), marshallingInfo);
-    }
-
-    /**
-     * @return The original value if non-null, or if value is null and a {@link com.amazonaws.protocol.DefaultValueSupplier} is
-     * present return the default value. Otherwise return null.
-     */
-    private <V> V resolveValue(V val, MarshallingInfo<V> marshallingInfo) {
-        return val == null && marshallingInfo.defaultValueSupplier() != null ? marshallingInfo.defaultValueSupplier().get() : val;
-    }
-
-    private <V> void doMarshall(V val, MarshallingInfo<V> marshallingInfo) {
-        if (marshallingInfo.isBinary()) {
-            marshallBinaryPayload(val);
-        } else {
-            marshallerRegistry.getMarshaller(marshallingInfo.marshallLocation(), marshallingInfo.marshallingType(), val)
-                              .marshall(val, marshallerContext, marshallingInfo.marshallLocationName());
-        }
-    }
-
-    /**
-     * Binary data should be placed as is, directly into the content.
-     */
-    private void marshallBinaryPayload(Object val) {
-        if (val instanceof ByteBuffer) {
-            request.setContent(BinaryUtils.toStream((ByteBuffer) val));
-        } else if (val instanceof InputStream) {
-            request.setContent((InputStream) val);
-        }
-    }
-
-    @Override
-    public Request<OrigRequest> finishMarshalling() {
-        // Content may already be set if the payload is binary data.
-        if (request.getContent() == null) {
-            // End the implicit request object if needed.
-            if (!hasExplicitPayloadMember) {
-                jsonGenerator.writeEndObject();
-            }
-
-            byte[] content = jsonGenerator.getBytes();
-            request.setContent(new ByteArrayInputStream(content));
-            if (content.length > 0) {
-                request.addHeader("Content-Length", Integer.toString(content.length));
-            }
-        }
-        if (!request.getHeaders().containsKey("Content-Type")) {
-            request.addHeader("Content-Type", contentType);
-        }
-        return request;
-    }
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/MarshallerRegistry.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/MarshallerRegistry.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/MarshallerRegistry.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/MarshallerRegistry.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,181 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.protocol.MarshallLocation;
-import com.amazonaws.protocol.MarshallingType;
-import com.amazonaws.protocol.StructuredPojo;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-@SdkInternalApi
-public class MarshallerRegistry {
-
-    private final Map<MarshallLocation, Map<MarshallingType, JsonMarshaller<?>>> marshallers;
-    private final Set<MarshallingType<?>> marshallingTypes;
-    private final Map<Class<?>, MarshallingType<?>> marshallingTypeCache;
-
-    private MarshallerRegistry(Builder builder) {
-        this.marshallers = builder.marshallers;
-        this.marshallingTypes = builder.marshallingTypes;
-        this.marshallingTypeCache = new HashMap<Class<?>, MarshallingType<?>>(marshallingTypes.size());
-
-    }
-
-    public <T> JsonMarshaller<T> getMarshaller(MarshallLocation marshallLocation, T val) {
-        return getMarshaller(marshallLocation, toMarshallingType(val));
-    }
-
-    public <T> JsonMarshaller<T> getMarshaller(MarshallLocation marshallLocation, MarshallingType<T> marshallingType, T val) {
-        return getMarshaller(marshallLocation,
-                             val == null ? MarshallingType.NULL : marshallingType);
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T> JsonMarshaller<T> getMarshaller(MarshallLocation marshallLocation, MarshallingType<?> marshallingType) {
-        return (JsonMarshaller<T>) marshallers.get(marshallLocation).get(marshallingType);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> MarshallingType<T> toMarshallingType(T val) {
-        if (val == null) {
-            return (MarshallingType<T>) MarshallingType.NULL;
-        } else if (val instanceof StructuredPojo) {
-            // We don't want to cache every single POJO type so we make a special case of it here.
-            return (MarshallingType<T>) MarshallingType.STRUCTURED;
-        } else if (!marshallingTypeCache.containsKey(val.getClass())) {
-            return (MarshallingType<T>) populateMarshallingTypeCache(val.getClass());
-        }
-        return (MarshallingType<T>) marshallingTypeCache.get(val.getClass());
-    }
-
-    private MarshallingType<?> populateMarshallingTypeCache(Class<?> clzz) {
-        synchronized (marshallingTypeCache) {
-            if (!marshallingTypeCache.containsKey(clzz)) {
-                for (MarshallingType<?> marshallingType : marshallingTypes) {
-                    if (marshallingType.isDefaultMarshallerForType(clzz)) {
-                        marshallingTypeCache.put(clzz, marshallingType);
-                        return marshallingType;
-                    }
-                }
-                throw new SdkClientException("MarshallingType not found for class " + clzz);
-            }
-        }
-        return marshallingTypeCache.get(clzz);
-    }
-
-    /**
-     * Merge the given overrides with 'this' registry. Overrides are higher precedence than 'this' registry. Both 'this'
-     * registry and the override registry are immutable so a new registry object is returned. If the marshallerRegistryOverrides
-     * are null then this method just returns the current registry since there is nothing to merge.
-     *
-     * @param marshallerRegistryOverrides Override registry.
-     * @return New {@link MarshallerRegistry} with marshallers merged.
-     */
-    public MarshallerRegistry merge(MarshallerRegistry.Builder marshallerRegistryOverrides) {
-        if(marshallerRegistryOverrides == null) {
-            return this;
-        }
-        Builder merged = MarshallerRegistry.builder();
-        merged.copyMarshallersFromRegistry(this.marshallers);
-        merged.copyMarshallersFromRegistry(marshallerRegistryOverrides.marshallers);
-        return merged.build();
-    }
-
-    /**
-     * @return Builder instance to construct a {@link MarshallerRegistry}.
-     */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Builder for a {@link MarshallerRegistry}.
-     */
-    public static final class Builder {
-
-        private final Map<MarshallLocation, Map<MarshallingType, JsonMarshaller<?>>> marshallers
-                = new HashMap<MarshallLocation, Map<MarshallingType, JsonMarshaller<?>>>();
-        private final Set<MarshallingType<?>> marshallingTypes
-                = new HashSet<MarshallingType<?>>();
-
-        private Builder() {
-        }
-
-        public <T> Builder payloadMarshaller(MarshallingType<T> marshallingType,
-                                             JsonMarshaller<T> marshaller) {
-            return addMarshaller(MarshallLocation.PAYLOAD, marshallingType, marshaller);
-        }
-
-        public <T> Builder headerMarshaller(MarshallingType<T> marshallingType,
-                                            JsonMarshaller<T> marshaller) {
-            return addMarshaller(MarshallLocation.HEADER, marshallingType, marshaller);
-        }
-
-        public <T> Builder queryParamMarshaller(MarshallingType<T> marshallingType,
-                                                JsonMarshaller<T> marshaller) {
-            return addMarshaller(MarshallLocation.QUERY_PARAM, marshallingType, marshaller);
-        }
-
-        public <T> Builder pathParamMarshaller(MarshallingType<T> marshallingType,
-                                               JsonMarshaller<T> marshaller) {
-            return addMarshaller(MarshallLocation.PATH, marshallingType, marshaller);
-        }
-
-        public <T> Builder greedyPathParamMarshaller(MarshallingType<T> marshallingType,
-                                                     JsonMarshaller<T> marshaller) {
-            return addMarshaller(MarshallLocation.GREEDY_PATH, marshallingType, marshaller);
-        }
-
-        public <T> Builder addMarshaller(MarshallLocation marshallLocation,
-                                         MarshallingType<T> marshallingType,
-                                         JsonMarshaller<T> marshaller) {
-            marshallingTypes.add(marshallingType);
-            if (!marshallers.containsKey(marshallLocation)) {
-                marshallers.put(marshallLocation, new HashMap<MarshallingType, JsonMarshaller<?>>());
-            }
-            marshallers.get(marshallLocation).put(marshallingType, marshaller);
-            return this;
-        }
-
-        /**
-         * @return An immutable {@link MarshallerRegistry} object.
-         */
-        public MarshallerRegistry build() {
-            return new MarshallerRegistry(this);
-        }
-
-        /**
-         * Fill this builder with marshallers from the source {@link MarshallerRegistry}. Will overwrite anything that is
-         * registered with the same location and type.
-         *
-         * @param sourceMarshallers Marshallers to copy in.
-         */
-        private void copyMarshallersFromRegistry(
-                Map<MarshallLocation, Map<MarshallingType, JsonMarshaller<?>>> sourceMarshallers) {
-
-            for (Map.Entry<MarshallLocation, Map<MarshallingType, JsonMarshaller<?>>> byLocationEntry :
-                    sourceMarshallers.entrySet()) {
-                for (Map.Entry<MarshallingType, JsonMarshaller<?>> byTypeEntry : byLocationEntry.getValue().entrySet()) {
-                    this.addMarshaller(byLocationEntry.getKey(), byTypeEntry.getKey(), byTypeEntry.getValue());
-                }
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/NullAsEmptyBodyProtocolRequestMarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/NullAsEmptyBodyProtocolRequestMarshaller.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/NullAsEmptyBodyProtocolRequestMarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/NullAsEmptyBodyProtocolRequestMarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,55 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.Request;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.protocol.MarshallingInfo;
-import com.amazonaws.protocol.ProtocolRequestMarshaller;
-
-/**
- * AWS services expect an empty body when the payload member is null instead of an explicit JSON null.
- * This implementation can be removed once CR-6541513 has been deployed to all services that use the payload trait.
- *
- * @param <OrigRequest> Type of the original request object.
- */
-@SdkInternalApi
-public class NullAsEmptyBodyProtocolRequestMarshaller<OrigRequest> implements ProtocolRequestMarshaller<OrigRequest> {
-
-    private final ProtocolRequestMarshaller<OrigRequest> delegate;
-
-    public NullAsEmptyBodyProtocolRequestMarshaller(ProtocolRequestMarshaller<OrigRequest> delegate) {
-        this.delegate = delegate;
-    }
-
-    @Override
-    public void startMarshalling() {
-        delegate.startMarshalling();
-    }
-
-    @Override
-    public <V> void marshall(V val, MarshallingInfo<V> marshallingInfo) {
-        // If the payload member is null then don't marshall it (since it will become an explicit null)
-        if (marshallingInfo.isExplicitPayloadMember() && val == null) {
-            return;
-        }
-        delegate.marshall(val, marshallingInfo);
-    }
-
-    @Override
-    public Request<OrigRequest> finishMarshalling() {
-        return delegate.finishMarshalling();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/QueryParamMarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/QueryParamMarshallers.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/QueryParamMarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/QueryParamMarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,78 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.protocol.MarshallLocation;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-@SdkInternalApi
-public class QueryParamMarshallers {
-
-    public static final JsonMarshaller<String> STRING = new SimpleQueryParamMarshaller<String>(
-            ValueToStringConverters.FROM_STRING);
-
-    public static final JsonMarshaller<Integer> INTEGER = new SimpleQueryParamMarshaller<Integer>(
-            ValueToStringConverters.FROM_INTEGER);
-
-    public static final JsonMarshaller<Long> LONG = new SimpleQueryParamMarshaller<Long>(ValueToStringConverters.FROM_LONG);
-
-    public static final JsonMarshaller<Double> DOUBLE = new SimpleQueryParamMarshaller<Double>(
-            ValueToStringConverters.FROM_DOUBLE);
-
-    public static final JsonMarshaller<Float> FLOAT = new SimpleQueryParamMarshaller<Float>(
-            ValueToStringConverters.FROM_FLOAT);
-
-    public static final JsonMarshaller<Boolean> BOOLEAN = new SimpleQueryParamMarshaller<Boolean>(
-            ValueToStringConverters.FROM_BOOLEAN);
-
-    public static final JsonMarshaller<Date> DATE = new SimpleQueryParamMarshaller<Date>(ValueToStringConverters.FROM_DATE);
-
-    public static final JsonMarshaller<List> LIST = new JsonMarshaller<List>() {
-        @Override
-        public void marshall(List list, JsonMarshallerContext context, String paramName) {
-            for (Object listVal : list) {
-                context.marshall(MarshallLocation.QUERY_PARAM, listVal, paramName);
-            }
-        }
-    };
-
-    public static final JsonMarshaller<Map> MAP = new JsonMarshaller<Map>() {
-
-        @Override
-        public void marshall(Map val, JsonMarshallerContext context, String paramName) {
-            for (Map.Entry<String, ?> mapEntry : ((Map<String, ?>) val).entrySet()) {
-                context.marshall(MarshallLocation.QUERY_PARAM, mapEntry.getValue(), mapEntry.getKey());
-            }
-        }
-    };
-
-    private static class SimpleQueryParamMarshaller<T> implements JsonMarshaller<T> {
-
-        private final ValueToStringConverters.ValueToString<T> converter;
-
-        private SimpleQueryParamMarshaller(ValueToStringConverters.ValueToString<T> converter) {
-            this.converter = converter;
-        }
-
-        @Override
-        public void marshall(T val, JsonMarshallerContext context, String paramName) {
-            context.request().addParameter(paramName, converter.convert(val));
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/SimpleTypeJsonMarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/SimpleTypeJsonMarshallers.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/SimpleTypeJsonMarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/SimpleTypeJsonMarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,205 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.internal.SdkInternalList;
-import com.amazonaws.internal.SdkInternalMap;
-import com.amazonaws.protocol.MarshallLocation;
-import com.amazonaws.protocol.StructuredPojo;
-import com.amazonaws.protocol.json.StructuredJsonGenerator;
-import com.amazonaws.protocol.json.StructuredJsonMarshaller;
-import java.math.BigDecimal;
-import java.nio.ByteBuffer;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-@SdkInternalApi
-public class SimpleTypeJsonMarshallers {
-
-    public static final JsonMarshaller<Void> NULL = new JsonMarshaller<Void>() {
-        @Override
-        public void marshall(Void val, JsonMarshallerContext context, String paramName) {
-            // If paramName is non null then we are emitting a field of an object, in that
-            // we just don't write the field. If param name is null then we are either in a container
-            // or the thing being marshalled is the payload itself in which case we want to preserve
-            // the JSON null.
-            if (paramName == null) {
-                context.jsonGenerator().writeNull();
-            }
-        }
-    };
-
-    public static final JsonMarshaller<String> STRING = new BaseJsonMarshaller<String>() {
-        @Override
-        public void marshall(String val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<Integer> INTEGER = new BaseJsonMarshaller<Integer>() {
-        @Override
-        public void marshall(Integer val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<Long> LONG = new BaseJsonMarshaller<Long>() {
-        @Override
-        public void marshall(Long val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<Float> FLOAT = new BaseJsonMarshaller<Float>() {
-        @Override
-        public void marshall(Float val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<BigDecimal> BIG_DECIMAL = new BaseJsonMarshaller<BigDecimal>() {
-        @Override
-        public void marshall(BigDecimal val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<Double> DOUBLE = new BaseJsonMarshaller<Double>() {
-        @Override
-        public void marshall(Double val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<Boolean> BOOLEAN = new BaseJsonMarshaller<Boolean>() {
-        @Override
-        public void marshall(Boolean val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<Date> DATE = new BaseJsonMarshaller<Date>() {
-        @Override
-        public void marshall(Date val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<ByteBuffer> BYTE_BUFFER = new BaseJsonMarshaller<ByteBuffer>() {
-        @Override
-        public void marshall(ByteBuffer val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeValue(val);
-        }
-    };
-
-    public static final JsonMarshaller<StructuredPojo> STRUCTURED = new BaseJsonMarshaller<StructuredPojo>() {
-        @Override
-        public void marshall(StructuredPojo val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeStartObject();
-            val.marshall(context.protocolHandler());
-            jsonGenerator.writeEndObject();
-
-        }
-    };
-
-    public static final JsonMarshaller<List> LIST = new BaseJsonMarshaller<List>() {
-        @Override
-        public void marshall(List list, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeStartArray();
-            for (Object listValue : list) {
-                context.marshall(MarshallLocation.PAYLOAD, listValue);
-            }
-            jsonGenerator.writeEndArray();
-        }
-
-        @Override
-        protected boolean shouldEmit(List list) {
-            return !(list.isEmpty() && list instanceof SdkInternalList && ((SdkInternalList) list).isAutoConstruct());
-        }
-    };
-
-    /**
-     * Marshalls a Map as a JSON object where each key becomes a field.
-     */
-    public static final JsonMarshaller<Map> MAP = new BaseJsonMarshaller<Map>() {
-        @Override
-        public void marshall(Map map, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-            jsonGenerator.writeStartObject();
-            for (Map.Entry<String, ?> entry : ((Map<String, ?>) map).entrySet()) {
-                if (entry.getValue() != null) {
-                    final Object value = entry.getValue();
-                    jsonGenerator.writeFieldName(entry.getKey());
-                    context.marshall(MarshallLocation.PAYLOAD, value);
-                }
-            }
-            jsonGenerator.writeEndObject();
-        }
-
-        @Override
-        protected boolean shouldEmit(Map map) {
-            return !(map.isEmpty() && map instanceof SdkInternalMap && ((SdkInternalMap) map).isAutoConstruct());
-        }
-    };
-
-    /**
-     * Adapt a {@link StructuredJsonMarshaller} to a {@link JsonMarshaller}. {@link JsonMarshaller} has a lot of internal
-     * stuff so we don't want to expose all that across module boundaries.
-     *
-     * @param toAdapt Marshaller to adapt.
-     * @param <T>     Type of thing being marshalled.
-     * @return Adapted marshaller.
-     */
-    public static <T> JsonMarshaller<T> adapt(final StructuredJsonMarshaller<T> toAdapt) {
-        return new BaseJsonMarshaller<T>() {
-            @Override
-            public void marshall(T val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context) {
-                toAdapt.marshall(val, jsonGenerator);
-            }
-        };
-    }
-
-    /**
-     * Base marshaller that emits the field name if present. The field name may be null in cases like
-     * marshalling something inside a list or if the object is the explicit payload member.
-     *
-     * @param <T> Type to marshall.
-     */
-    private abstract static class BaseJsonMarshaller<T> implements JsonMarshaller<T> {
-
-        @Override
-        public final void marshall(T val, JsonMarshallerContext context, String paramName) {
-            if (!shouldEmit(val)) {
-                return;
-            }
-            if (paramName != null) {
-                context.jsonGenerator().writeFieldName(paramName);
-            }
-            marshall(val, context.jsonGenerator(), context);
-        }
-
-        public abstract void marshall(T val, StructuredJsonGenerator jsonGenerator, JsonMarshallerContext context);
-
-        /**
-         * Hook to prevent emitting the field name. Used for maps and lists since we treat empty auto constructed
-         * containers as null.
-         */
-        protected boolean shouldEmit(T val) {
-            return true;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/SimpleTypePathMarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/SimpleTypePathMarshallers.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/SimpleTypePathMarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/SimpleTypePathMarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,65 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.transform.PathMarshallers;
-
-@SdkInternalApi
-public class SimpleTypePathMarshallers {
-
-    public static final JsonMarshaller<String> STRING =
-            new SimplePathMarshaller<String>(ValueToStringConverters.FROM_STRING, PathMarshallers.NON_GREEDY);
-
-    public static final JsonMarshaller<Integer> INTEGER =
-            new SimplePathMarshaller<Integer>(ValueToStringConverters.FROM_INTEGER, PathMarshallers.NON_GREEDY);
-
-    public static final JsonMarshaller<Long> LONG =
-            new SimplePathMarshaller<Long>(ValueToStringConverters.FROM_LONG, PathMarshallers.NON_GREEDY);
-
-    /**
-     * Marshallers for Strings bound to a greedy path param. No URL encoding is done on the string
-     * so that it preserves the path structure.
-     */
-    public static final JsonMarshaller<String> GREEDY_STRING =
-            new SimplePathMarshaller<String>(ValueToStringConverters.FROM_STRING, PathMarshallers.GREEDY);
-
-    public static final JsonMarshaller<Void> NULL = new JsonMarshaller<Void>() {
-        @Override
-        public void marshall(Void val, JsonMarshallerContext context, String paramName) {
-            throw new IllegalArgumentException(String.format("Parameter '%s' must not be null", paramName));
-        }
-    };
-
-    private static class SimplePathMarshaller<T> implements JsonMarshaller<T> {
-
-        private final ValueToStringConverters.ValueToString<T> converter;
-        private final PathMarshallers.PathMarshaller pathMarshaller;
-
-        private SimplePathMarshaller(ValueToStringConverters.ValueToString<T> converter,
-                                     PathMarshallers.PathMarshaller pathMarshaller) {
-            this.converter = converter;
-            this.pathMarshaller = pathMarshaller;
-        }
-
-        @Override
-        public void marshall(T val, JsonMarshallerContext context, String paramName) {
-            context.request().setResourcePath(
-                    pathMarshaller.marshall(context.request().getResourcePath(), paramName, converter.convert(val)));
-        }
-
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/internal/ValueToStringConverters.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/ValueToStringConverters.java
--- ./src/main/java/com/amazonaws/protocol/json/internal/ValueToStringConverters.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/internal/ValueToStringConverters.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,105 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json.internal;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.Base64;
-import com.amazonaws.util.StringUtils;
-import java.nio.charset.Charset;
-import java.util.Date;
-
-/**
- * Converts various types to Strings. Used for Query Param/Header/Path marshalling.
- */
-@SdkInternalApi
-public class ValueToStringConverters {
-
-    /**
-     * Simple interface to convert a type to a String.
-     *
-     * @param <T> Type to convert.
-     */
-    public interface ValueToString<T> {
-        String convert(T val);
-    }
-
-    /**
-     * Identity converter.
-     */
-    public static final ValueToString<String> FROM_STRING = new ValueToString<String>() {
-        @Override
-        public String convert(String val) {
-            return val;
-        }
-    };
-
-    public static final ValueToString<Integer> FROM_INTEGER = new ValueToString<Integer>() {
-        @Override
-        public String convert(Integer val) {
-            return StringUtils.fromInteger(val);
-        }
-    };
-
-    public static final ValueToString<Long> FROM_LONG = new ValueToString<Long>() {
-        @Override
-        public String convert(Long val) {
-            return StringUtils.fromLong(val);
-        }
-    };
-
-    public static final ValueToString<Float> FROM_FLOAT = new ValueToString<Float>() {
-        @Override
-        public String convert(Float val) {
-            return StringUtils.fromFloat(val);
-        }
-    };
-
-    public static final ValueToString<Double> FROM_DOUBLE = new ValueToString<Double>() {
-        @Override
-        public String convert(Double val) {
-            return StringUtils.fromDouble(val);
-        }
-    };
-
-    /**
-     * Marshalls boolean as a literal 'true' or 'false' string.
-     */
-    public static final ValueToString<Boolean> FROM_BOOLEAN = new ValueToString<Boolean>() {
-        @Override
-        public String convert(Boolean val) {
-            return StringUtils.fromBoolean(val);
-        }
-    };
-
-    /**
-     * Marshalls date to an ISO8601 date string.
-     */
-    public static final ValueToString<Date> FROM_DATE = new ValueToString<Date>() {
-        @Override
-        public String convert(Date val) {
-            return StringUtils.fromDate(val);
-        }
-    };
-
-    /**
-     * Converter for JSON value headers. JSON value headers are base-64 encoded.
-     */
-    public static final ValueToString<String> FROM_JSON_VALUE_HEADER = new ValueToString<String>() {
-        @Override
-        public String convert(String val) {
-            return Base64.encodeAsString(val.getBytes(Charset.forName("utf-8")));
-        }
-    };
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/IonFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/IonFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/IonFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/IonFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,88 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not
- * use this file except in compliance with the License. A copy of the License is
- * located at
- * 
- * http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.net.URL;
-
-import software.amazon.ion.IonSystem;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.core.JsonParser;
-
-class IonFactory extends JsonFactory {
-    private static final long serialVersionUID = 1;
-
-    private static final boolean SHOULD_CLOSE_READER_YES = true;
-    private static final boolean SHOULD_CLOSE_READER_NO = false;
-
-    // TODO IonReaderBuilder will soon be available for constructing IonReaders
-    // without an IonSystem. This should use an IonReaderBuilder.
-    private transient final IonSystem ionSystem;
-
-    public IonFactory(IonSystem ionSystem) {
-        this.ionSystem = ionSystem;
-    }
-
-    @Override
-    public JsonParser createParser(InputStream in) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(in), SHOULD_CLOSE_READER_NO);
-    }
-
-    @Override
-    public JsonParser createParser(byte[] data) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(data), SHOULD_CLOSE_READER_NO);
-    }
-
-    @Override
-    public JsonParser createParser(byte[] data, int offset, int length) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(data, offset, length), SHOULD_CLOSE_READER_NO);
-    }
-
-    @Override
-    public JsonParser createParser(char[] data) throws IOException, JsonParseException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public JsonParser createParser(char[] data, int offset, int length) throws IOException, JsonParseException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public JsonParser createParser(String data) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(data), SHOULD_CLOSE_READER_NO);
-    }
-
-    @Override
-    public JsonParser createParser(Reader data) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(data), SHOULD_CLOSE_READER_NO);
-    }
-
-    @Override
-    public JsonParser createParser(File data) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(new FileInputStream(data)), SHOULD_CLOSE_READER_YES);
-    }
-
-    @Override
-    public JsonParser createParser(URL data) throws IOException, JsonParseException {
-        return new IonParser(ionSystem.newReader(data.openStream()), SHOULD_CLOSE_READER_YES);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/IonParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/IonParser.java
--- ./src/main/java/com/amazonaws/protocol/json/IonParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/IonParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,399 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not
- * use this file except in compliance with the License. A copy of the License is
- * located at
- * 
- * http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-
-import com.amazonaws.SdkClientException;
-import com.fasterxml.jackson.core.Base64Variant;
-import com.fasterxml.jackson.core.JsonLocation;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonStreamContext;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.core.JsonTokenId;
-import com.fasterxml.jackson.core.ObjectCodec;
-import com.fasterxml.jackson.core.Version;
-
-import software.amazon.ion.IonReader;
-import software.amazon.ion.IonType;
-
-final class IonParser extends JsonParser {
-    private enum State {
-        BEFORE_VALUE,
-        END_OF_CONTAINER,
-        EOF,
-        FIELD_NAME,
-        VALUE
-    }
-
-    private final IonReader reader;
-    private final boolean shouldCloseReader;
-
-    private State state = State.BEFORE_VALUE;
-    private JsonToken currentToken;
-    private JsonToken lastClearedToken;
-    private boolean shouldSkipContainer;
-    private boolean closed;
-
-    public IonParser(IonReader reader, boolean shouldCloseReader) {
-        super(Feature.collectDefaults());
-        this.reader = reader;
-        this.shouldCloseReader = shouldCloseReader;
-    }
-
-    @Override
-    public ObjectCodec getCodec() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setCodec(ObjectCodec c) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Version version() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (shouldCloseReader) {
-            reader.close();
-        } else if (Feature.AUTO_CLOSE_SOURCE.enabledIn(_features)) {
-            reader.close();
-        }
-        closed = true;
-    }
-
-    @Override
-    public JsonToken nextToken() throws IOException, JsonParseException {
-        currentToken = doNextToken();
-        return currentToken;
-    }
-
-    private JsonToken doNextToken() {
-        for (;;) {
-            switch (state) {
-                case BEFORE_VALUE:
-                    IonType currentType = reader.next();
-
-                    if (currentType == null) {
-                        boolean topLevel = reader.getDepth() == 0;
-                        if (topLevel) {
-                            state = State.EOF;
-                            continue;
-                        } else {
-                            state = State.END_OF_CONTAINER;
-                            return reader.isInStruct()
-                                    ? JsonToken.END_OBJECT
-                                    : JsonToken.END_ARRAY;
-                        }
-                    }
-
-                    if (reader.isInStruct()) {
-                        state = State.FIELD_NAME;
-                        return JsonToken.FIELD_NAME;
-                    } else {
-                        state = State.VALUE;
-                        return getJsonToken();
-                    }
-
-                case END_OF_CONTAINER:
-                    reader.stepOut();
-                    state = State.BEFORE_VALUE;
-                    continue;
-
-                case EOF:
-                    return null;
-
-                case FIELD_NAME:
-                    state = State.VALUE;
-                    return getJsonToken();
-
-                case VALUE:
-                    state = State.BEFORE_VALUE;
-                    if (IonType.isContainer(reader.getType()) && !reader.isNullValue() && !shouldSkipContainer) {
-                        reader.stepIn();
-                    }
-                    shouldSkipContainer = false;
-                    continue;
-            }
-        }
-    }
-
-    @Override
-    public JsonToken nextValue() throws IOException, JsonParseException {
-        JsonToken token = nextToken();
-        return (token == JsonToken.FIELD_NAME)
-                ? nextToken()
-                : token;
-    }
-
-    @Override
-    public JsonParser skipChildren() throws IOException, JsonParseException {
-        IonType currentType = reader.getType();
-        if (IonType.isContainer(currentType)) {
-            shouldSkipContainer = true;
-            currentToken = currentType == IonType.STRUCT
-                    ? JsonToken.END_OBJECT
-                    : JsonToken.END_ARRAY;
-        }
-        return this;
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closed;
-    }
-
-    @Override
-    public JsonToken getCurrentToken() {
-        return currentToken;
-    }
-
-    @Override
-    public int getCurrentTokenId() {
-        return currentToken == null
-                ? JsonTokenId.ID_NO_TOKEN
-                : currentToken.id();
-    }
-
-    @Override
-    public boolean hasCurrentToken() {
-        return currentToken != null;
-    }
-
-    @Override
-    public boolean hasTokenId(int id) {
-        return getCurrentTokenId() == id;
-    }
-
-    @Override
-    public boolean hasToken(JsonToken t) {
-        return currentToken == t;
-    }
-
-    @Override
-    public String getCurrentName() throws IOException {
-        return reader.getFieldName();
-    }
-
-    @Override
-    public JsonStreamContext getParsingContext() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public JsonLocation getTokenLocation() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public JsonLocation getCurrentLocation() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearCurrentToken() {
-        lastClearedToken = currentToken;
-        currentToken = null;
-    }
-
-    @Override
-    public JsonToken getLastClearedToken() {
-        return lastClearedToken;
-    }
-
-    @Override
-    public void overrideCurrentName(String name) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getText() throws IOException {
-        if (state == State.FIELD_NAME) {
-            return reader.getFieldName();
-        }
-        if (IonType.isText(reader.getType())) {
-            return reader.stringValue();
-        }
-        if (currentToken == null)
-        {
-            // start or end of stream
-            return null;
-        }
-        if (currentToken.isNumeric()) {
-            return getNumberValue().toString();
-        }
-        return currentToken.asString();
-    }
-
-    @Override
-    public char[] getTextCharacters() throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getTextLength() throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getTextOffset() throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean hasTextCharacters() {
-        return false;
-    }
-
-    @Override
-    public Number getNumberValue() throws IOException {
-        NumberType numberType = getNumberType();
-        if (numberType == null) {
-            throw new SdkClientException(String.format("Unable to get number value for non-numeric token %s", reader.getType()));
-        }
-        switch (numberType) {
-            case BIG_DECIMAL:
-                return reader.bigDecimalValue();
-            case BIG_INTEGER:
-                return reader.bigIntegerValue();
-            case DOUBLE:
-                return reader.doubleValue();
-            default:
-                throw new SdkClientException(String.format("Unable to get number value for number type %s", numberType));
-        }
-    }
-
-    @Override
-    public NumberType getNumberType() throws IOException {
-        switch (reader.getType()) {
-            case DECIMAL:
-                return NumberType.BIG_DECIMAL;
-            case FLOAT:
-                return NumberType.DOUBLE;
-            case INT:
-                return NumberType.BIG_INTEGER;
-            default:
-                return null;
-        }
-    }
-
-    @Override
-    public int getIntValue() throws IOException {
-        return reader.intValue();
-    }
-
-    @Override
-    public long getLongValue() throws IOException {
-        return reader.longValue();
-    }
-
-    @Override
-    public BigInteger getBigIntegerValue() throws IOException {
-        return reader.bigIntegerValue();
-    }
-
-    @Override
-    public float getFloatValue() throws IOException {
-        return (float) reader.doubleValue();
-    }
-
-    @Override
-    public double getDoubleValue() throws IOException {
-        return reader.doubleValue();
-    }
-
-    @Override
-    public BigDecimal getDecimalValue() throws IOException {
-        return reader.decimalValue();
-    }
-
-    @Override
-    public Object getEmbeddedObject() throws IOException {
-        if (currentToken != JsonToken.VALUE_EMBEDDED_OBJECT) {
-            return null;
-        }
-        IonType currentType = reader.getType();
-        switch (currentType) {
-            case BLOB:
-            case CLOB:
-                return ByteBuffer.wrap(reader.newBytes());
-            case TIMESTAMP:
-                return reader.timestampValue().dateValue();
-            default:
-                throw new SdkClientException(String.format("Cannot return embedded object for Ion type %s", currentType));
-        }
-    }
-
-    @Override
-    public byte[] getBinaryValue(Base64Variant bv) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getValueAsString(String defaultValue) throws IOException {
-        // The documentation is ambiguous about whether field names should
-        // return their text or the default value. To conform with the
-        // CBORParser, they will get the default value here.
-        if (currentToken != JsonToken.VALUE_STRING) {
-            if (currentToken == null || currentToken == JsonToken.VALUE_NULL || !currentToken.isScalarValue()) {
-                return defaultValue;
-            }
-        }
-        return getText();
-    }
-
-    private JsonToken getJsonToken() {
-        if (reader.isNullValue()) {
-            return JsonToken.VALUE_NULL;
-        }
-
-        IonType currentType = reader.getType();
-        switch (currentType) {
-            case BLOB:
-            case CLOB:
-                return JsonToken.VALUE_EMBEDDED_OBJECT;
-            case BOOL:
-                return reader.booleanValue() ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE;
-            case DECIMAL:
-                return JsonToken.VALUE_NUMBER_FLOAT;
-            case FLOAT:
-                return JsonToken.VALUE_NUMBER_FLOAT;
-            case INT:
-                return JsonToken.VALUE_NUMBER_INT;
-            case LIST:
-                return JsonToken.START_ARRAY;
-            case SEXP:
-                return JsonToken.START_ARRAY;
-            case STRING:
-                return JsonToken.VALUE_STRING;
-            case STRUCT:
-                return JsonToken.START_OBJECT;
-            case SYMBOL:
-                return JsonToken.VALUE_STRING;
-            case TIMESTAMP:
-                return JsonToken.VALUE_EMBEDDED_OBJECT;
-            default:
-                throw new SdkClientException(String.format("Unhandled Ion type %s", currentType));
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonClientMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonClientMetadata.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonClientMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonClientMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,107 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Wrapper object to provide additional metadata about a client and protocol to {@link
- * SdkJsonProtocolFactory}
- */
-@NotThreadSafe
-@SdkProtectedApi
-public class JsonClientMetadata {
-
-    private final List<JsonErrorShapeMetadata> errorsMetadata = new ArrayList<JsonErrorShapeMetadata>();
-
-    private String protocolVersion;
-
-    private String contentTypeOverride;
-
-    private boolean supportsCbor;
-
-    private boolean supportsIon;
-
-    /**
-     * Base class is initialized to {@link AmazonServiceException} for backwards compatibility.
-     */
-    private Class<? extends RuntimeException> baseServiceExceptionClass = AmazonServiceException.class;
-
-    public JsonClientMetadata addErrorMetadata(JsonErrorShapeMetadata errorShapeMetadata) {
-        this.errorsMetadata.add(errorShapeMetadata);
-        return this;
-    }
-
-    public JsonClientMetadata addAllErrorMetadata(JsonErrorShapeMetadata... errorShapeMetadata) {
-        Collections.addAll(errorsMetadata, errorShapeMetadata);
-        return this;
-    }
-
-    public List<JsonErrorShapeMetadata> getErrorShapeMetadata() {
-        return errorsMetadata;
-    }
-
-    public String getProtocolVersion() {
-        return protocolVersion;
-    }
-
-    public JsonClientMetadata withProtocolVersion(String protocolVersion) {
-        this.protocolVersion = protocolVersion;
-        return this;
-    }
-
-    public String getContentTypeOverride() {
-        return contentTypeOverride;
-    }
-
-    public JsonClientMetadata withContentTypeOverride(String contentType) {
-        this.contentTypeOverride = contentType;
-        return this;
-    }
-
-    public boolean isSupportsCbor() {
-        return supportsCbor;
-    }
-
-    public JsonClientMetadata withSupportsCbor(boolean supportsCbor) {
-        this.supportsCbor = supportsCbor;
-        return this;
-    }
-
-    public Class<? extends RuntimeException> getBaseServiceExceptionClass() {
-        return baseServiceExceptionClass;
-    }
-
-    public boolean isSupportsIon() {
-        return supportsIon;
-    }
-
-    public JsonClientMetadata withSupportsIon(boolean supportsIon) {
-        this.supportsIon = supportsIon;
-        return this;
-    }
-
-    public JsonClientMetadata withBaseServiceExceptionClass(
-            Class<? extends RuntimeException> baseServiceExceptionClass) {
-        this.baseServiceExceptionClass = baseServiceExceptionClass;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonContent.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonContent.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonContent.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonContent.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,86 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.http.HttpResponse;
-import com.amazonaws.util.IOUtils;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Simple struct like class to hold both the raw json string content and it's parsed JsonNode
- */
-@SdkInternalApi
-public class JsonContent {
-
-    private static final Log LOG = LogFactory.getLog(JsonContent.class);
-
-    private final byte[] rawContent;
-    private final JsonNode jsonNode;
-
-    /**
-     * Static factory method to create a JsonContent object from the contents of the HttpResponse
-     * provided
-     */
-    public static JsonContent createJsonContent(HttpResponse httpResponse,
-                                                JsonFactory jsonFactory) {
-        byte[] rawJsonContent = null;
-        try {
-            if (httpResponse.getContent() != null) {
-                rawJsonContent = IOUtils.toByteArray(httpResponse.getContent());
-            }
-        } catch (Exception e) {
-            LOG.debug("Unable to read HTTP response content", e);
-        }
-        return new JsonContent(rawJsonContent, new ObjectMapper(jsonFactory)
-                .configure(JsonParser.Feature.ALLOW_COMMENTS, true));
-    }
-
-    public JsonContent(byte[] rawJsonContent, JsonNode jsonNode) {
-        this.rawContent = rawJsonContent;
-        this.jsonNode = jsonNode;
-    }
-
-    private JsonContent(byte[] rawJsonContent, ObjectMapper mapper) {
-        this.rawContent = rawJsonContent;
-        this.jsonNode = parseJsonContent(rawJsonContent, mapper);
-    }
-
-    private static JsonNode parseJsonContent(byte[] rawJsonContent, ObjectMapper mapper) {
-        if (rawJsonContent == null) {
-            return mapper.createObjectNode();
-        }
-        try {
-            return mapper.readTree(rawJsonContent);
-        } catch (Exception e) {
-            LOG.debug("Unable to parse HTTP response content", e);
-            return mapper.createObjectNode();
-        }
-    }
-
-    public byte[] getRawContent() {
-        return rawContent;
-    }
-
-    public JsonNode getJsonNode() {
-        return jsonNode;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolverImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolverImpl.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolverImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolverImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Prefers an explicit content type if provided. Otherwise computes the correct content type based
- * on the wire format used and the version of the protocol.
- */
-@SdkInternalApi
-class JsonContentTypeResolverImpl implements JsonContentTypeResolver {
-
-    private final String prefix;
-
-    JsonContentTypeResolverImpl(String prefix) {
-        this.prefix = prefix;
-    }
-
-    @Override
-    public String resolveContentType(JsonClientMetadata metadata) {
-        return metadata.getContentTypeOverride() != null ? metadata.getContentTypeOverride() :
-                prefix + metadata.getProtocolVersion();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolver.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolver.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolver.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonContentTypeResolver.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Interface to compute the content type to send in requests for JSON based protocols.
- */
-@SdkInternalApi
-interface JsonContentTypeResolver {
-
-    /**
-     * Content type resolver implementation for Ion-enabled services.
-     */
-    JsonContentTypeResolver ION_BINARY = new JsonContentTypeResolverImpl("application/x-amz-ion-");
-
-    /**
-     * Content type resolver implementation for debugging Ion-enabled services.
-     */
-    JsonContentTypeResolver ION_TEXT = new JsonContentTypeResolverImpl("text/x-amz-ion-");
-
-    /**
-     * Content type resolver implementation for CBOR enabled services.
-     */
-    JsonContentTypeResolver CBOR = new JsonContentTypeResolverImpl("application/x-amz-cbor-");
-
-    /**
-     * Content type resolver implementation for plain text JSON services.
-     */
-    JsonContentTypeResolver JSON = new JsonContentTypeResolverImpl("application/x-amz-json-");
-
-    /**
-     * Computes content type to send in requests.
-     *
-     * @param metadata Metadata about the client making the request.
-     * @return Correct content type to send in request based on metadata about the client.
-     */
-    String resolveContentType(JsonClientMetadata metadata);
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonErrorResponseMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonErrorResponseMetadata.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonErrorResponseMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonErrorResponseMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,58 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import java.util.List;
-
-/**
- * Contains various metadata needed to create an appropriate {@link com.amazonaws.http.JsonErrorResponseHandler}
- * for the client.
- */
-@NotThreadSafe
-@SdkProtectedApi
-public class JsonErrorResponseMetadata {
-
-    /**
-     * Custom error code field name in exceptional responses. Currently only used by glacier. If not
-     * set the default error code parser will be used.
-     */
-    private String customErrorCodeFieldName;
-
-    /**
-     * Error shapes scoped to a specific operation.
-     */
-    private List<JsonErrorShapeMetadata> errorShapes;
-
-    public String getCustomErrorCodeFieldName() {
-        return customErrorCodeFieldName;
-    }
-
-    public JsonErrorResponseMetadata withCustomErrorCodeFieldName(String errorCodeFieldName) {
-        this.customErrorCodeFieldName = errorCodeFieldName;
-        return this;
-    }
-
-    public List<JsonErrorShapeMetadata> getErrorShapes() {
-        return errorShapes;
-    }
-
-    public JsonErrorResponseMetadata withErrorShapes(List<JsonErrorShapeMetadata> errorShapes) {
-        this.errorShapes = errorShapes;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonErrorShapeMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonErrorShapeMetadata.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonErrorShapeMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonErrorShapeMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,61 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Wrapper object to provide additional metadata about a client's error shapes to {@link
- * SdkJsonProtocolFactory}
- */
-@NotThreadSafe
-@SdkProtectedApi
-public class JsonErrorShapeMetadata {
-
-    private String errorCode;
-
-    private Integer httpStatusCode;
-
-    private Class<? extends RuntimeException> modeledClass;
-
-
-    public String getErrorCode() {
-        return errorCode;
-    }
-
-    public JsonErrorShapeMetadata withErrorCode(String errorCode) {
-        this.errorCode = errorCode;
-        return this;
-    }
-
-    public Integer getHttpStatusCode() {
-        return httpStatusCode;
-    }
-
-    public JsonErrorShapeMetadata withHttpStatusCode(Integer httpStatusCode) {
-        this.httpStatusCode = httpStatusCode;
-        return this;
-    }
-
-    public Class<? extends RuntimeException> getModeledClass() {
-        return modeledClass;
-    }
-
-    public JsonErrorShapeMetadata withModeledClass(Class<? extends RuntimeException> modeledClass) {
-        this.modeledClass = modeledClass;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonOperationMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonOperationMetadata.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonOperationMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonOperationMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.Unmarshaller;
-
-/**
- * Contains various information needed to create a {@link com.amazonaws.http.JsonResponseHandler}
- * for the client.
- */
-@NotThreadSafe
-@SdkProtectedApi
-public class JsonOperationMetadata {
-
-    private boolean hasStreamingSuccessResponse;
-    private boolean isPayloadJson;
-
-    public boolean isHasStreamingSuccessResponse() {
-        return hasStreamingSuccessResponse;
-    }
-
-    public JsonOperationMetadata withHasStreamingSuccessResponse(
-            boolean hasStreamingSuccessResponse) {
-        this.hasStreamingSuccessResponse = hasStreamingSuccessResponse;
-        return this;
-    }
-
-    public boolean isPayloadJson() {
-        return isPayloadJson;
-    }
-
-    public JsonOperationMetadata withPayloadJson(boolean payloadJson) {
-        isPayloadJson = payloadJson;
-        return this;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/JsonProtocolMarshallerBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonProtocolMarshallerBuilder.java
--- ./src/main/java/com/amazonaws/protocol/json/JsonProtocolMarshallerBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/JsonProtocolMarshallerBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,105 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.protocol.MarshallLocation;
-import com.amazonaws.protocol.MarshallingType;
-import com.amazonaws.protocol.OperationInfo;
-import com.amazonaws.protocol.ProtocolMarshaller;
-import com.amazonaws.protocol.ProtocolRequestMarshaller;
-import com.amazonaws.protocol.json.internal.JsonProtocolMarshaller;
-import com.amazonaws.protocol.json.internal.MarshallerRegistry;
-import com.amazonaws.protocol.json.internal.NullAsEmptyBodyProtocolRequestMarshaller;
-import com.amazonaws.protocol.json.internal.SimpleTypeJsonMarshallers;
-
-/**
- * Builder to create an appropriate implementation of {@link ProtocolMarshaller} for JSON based services.
- *
- * @param <T> Type of the original request object.
- */
-@SdkProtectedApi
-public class JsonProtocolMarshallerBuilder<T> {
-
-    private StructuredJsonGenerator jsonGenerator;
-    private String contentType;
-    private OperationInfo operationInfo;
-    private boolean sendExplicitNullForPayload;
-    private T originalRequest;
-    private MarshallerRegistry.Builder marshallerRegistry;
-
-    public static <T> JsonProtocolMarshallerBuilder<T> standard() {
-        return new JsonProtocolMarshallerBuilder<T>();
-    }
-
-    public JsonProtocolMarshallerBuilder<T> jsonGenerator(StructuredJsonGenerator jsonGenerator) {
-        this.jsonGenerator = jsonGenerator;
-        return this;
-    }
-
-    public JsonProtocolMarshallerBuilder<T> contentType(String contentType) {
-        this.contentType = contentType;
-        return this;
-    }
-
-    public JsonProtocolMarshallerBuilder<T> operationInfo(OperationInfo operationInfo) {
-        this.operationInfo = operationInfo;
-        return this;
-    }
-
-    /**
-     * @param sendExplicitNullForPayload True if an explicit JSON null should be sent as the body when the
-     *                                   payload member is null. See {@link NullAsEmptyBodyProtocolRequestMarshaller}.
-     */
-    public JsonProtocolMarshallerBuilder<T> sendExplicitNullForPayload(boolean sendExplicitNullForPayload) {
-        this.sendExplicitNullForPayload = sendExplicitNullForPayload;
-        return this;
-    }
-
-    public JsonProtocolMarshallerBuilder<T> originalRequest(T originalRequest) {
-        this.originalRequest = originalRequest;
-        return this;
-    }
-
-    /**
-     * Registers an override for the marshaller registry.
-     *
-     * @param marshallLocation Location to override marshaller for.
-     * @param marshallingType  Type to override marshaller for.
-     * @param marshaller       Marshaller to use for the given location and type.
-     * @param <MarshallT>      Type of thing being marshalled.
-     * @return This builder for method chaining.
-     */
-    public <MarshallT> JsonProtocolMarshallerBuilder<T> marshallerOverride(MarshallLocation marshallLocation,
-                                                                           MarshallingType<MarshallT> marshallingType,
-                                                                           StructuredJsonMarshaller<MarshallT> marshaller) {
-        if (marshallerRegistry == null) {
-            this.marshallerRegistry = MarshallerRegistry.builder();
-        }
-        marshallerRegistry.addMarshaller(marshallLocation, marshallingType, SimpleTypeJsonMarshallers.adapt(marshaller));
-        return this;
-    }
-
-    public ProtocolRequestMarshaller<T> build() {
-        final ProtocolRequestMarshaller<T> protocolMarshaller = new JsonProtocolMarshaller<T>(jsonGenerator,
-                                                                                              contentType,
-                                                                                              operationInfo,
-                                                                                              originalRequest,
-                                                                                              marshallerRegistry);
-        return sendExplicitNullForPayload ? protocolMarshaller :
-                new NullAsEmptyBodyProtocolRequestMarshaller<T>(protocolMarshaller);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkCborGenerator.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkCborGenerator.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkCborGenerator.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkCborGenerator.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,77 +0,0 @@
-/*
- *
- * Copyright (c) 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
-
-import java.io.IOException;
-import java.util.Date;
-
-import static com.amazonaws.SDKGlobalConfiguration.AWS_CBOR_DISABLE_ENV_VAR;
-import static com.amazonaws.SDKGlobalConfiguration.AWS_CBOR_DISABLE_SYSTEM_PROPERTY;
-
-/**
- * Thin wrapper around Jackson's JSON generator for CBOR.
- */
-@SdkInternalApi
-class SdkCborGenerator extends SdkJsonGenerator {
-
-    private static final int CBOR_TAG_TIMESTAP = 1;
-
-    public SdkCborGenerator(JsonFactory factory, String contentType) {
-        super(factory, contentType);
-    }
-
-    /**
-     * Jackson doesn't have native support for timestamp. As per the RFC 7049
-     * (https://tools.ietf.org/html/rfc7049#section-2.4.1) we will need to
-     * write a tag and write the epoch.
-     */
-    @Override
-    public StructuredJsonGenerator writeValue(Date date) {
-
-        if (!(getGenerator() instanceof CBORGenerator)) {
-            throw new IllegalStateException("SdkCborGenerator is not created with a CBORGenerator.");
-        }
-
-        CBORGenerator generator = (CBORGenerator) getGenerator();
-        try {
-            generator.writeTag(CBOR_TAG_TIMESTAP);
-            generator.writeNumber(date.getTime());
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public byte[] getBytes() {
-        try {
-            return super.getBytes();
-        } catch (NoSuchMethodError e) {
-            throw new RuntimeException(
-                    "Jackson jackson-core/jackson-dataformat-cbor incompatible library version detected.\nYou have two possible resolutions:\n" +
-                            "\t\t1) Ensure the com.fasterxml.jackson.core:jackson-core & com.fasterxml.jackson.dataformat:jackson-dataformat-cbor libraries " +
-                            "on your classpath have the same version number\n" +
-                            "\t\t2) Disable CBOR wire-protocol by passing the -D" + AWS_CBOR_DISABLE_SYSTEM_PROPERTY + " property or setting the " +
-                            AWS_CBOR_DISABLE_ENV_VAR + " environment variable (warning this may affect performance)",
-                    e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkIonGenerator.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkIonGenerator.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkIonGenerator.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkIonGenerator.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,240 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.util.BinaryUtils;
-import software.amazon.ion.IonType;
-import software.amazon.ion.IonWriter;
-import software.amazon.ion.Timestamp;
-import software.amazon.ion.system.IonWriterBuilder;
-
-@SdkInternalApi
-abstract class SdkIonGenerator implements StructuredJsonGenerator {
-    private final String contentType;
-    protected final IonWriter writer;
-
-    private SdkIonGenerator(IonWriter writer, String contentType) {
-        this.writer = writer;
-        this.contentType = contentType;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeStartArray() {
-        try {
-            writer.stepIn(IonType.LIST);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeNull() {
-        try {
-            writer.writeNull();
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeEndArray() {
-        try {
-            writer.stepOut();
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeStartObject() {
-        try {
-            writer.stepIn(IonType.STRUCT);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeEndObject() {
-        try {
-            writer.stepOut();
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeFieldName(String fieldName) {
-        writer.setFieldName(fieldName);
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(String val) {
-        try {
-            writer.writeString(val);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(boolean bool) {
-        try {
-            writer.writeBool(bool);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(long val) {
-        try {
-            writer.writeInt(val);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(double val) {
-        try {
-            writer.writeFloat(val);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(float val) {
-        try {
-            writer.writeFloat(val);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(short val) {
-        try {
-            writer.writeInt(val);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(int val) {
-        try {
-            writer.writeInt(val);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(ByteBuffer bytes) {
-        try {
-            writer.writeBlob(BinaryUtils.copyAllBytesFrom(bytes));
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(Date date) {
-        try {
-            writer.writeTimestamp(Timestamp.forDateZ(date));
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(BigDecimal value) {
-        try {
-            writer.writeDecimal(value);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(BigInteger value) {
-        try {
-            writer.writeInt(value);
-        } catch (IOException e) {
-            throw new SdkClientException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public abstract byte[] getBytes();
-
-    @Override
-    public String getContentType() {
-        return contentType;
-    }
-
-    public static SdkIonGenerator create(IonWriterBuilder builder, String contentType) {
-        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-        IonWriter writer = builder.build(bytes);
-        return new ByteArraySdkIonGenerator(bytes, writer, contentType);
-    }
-
-    private static class ByteArraySdkIonGenerator extends SdkIonGenerator {
-        private final ByteArrayOutputStream bytes;
-
-        public ByteArraySdkIonGenerator(ByteArrayOutputStream bytes, IonWriter writer, String contentType) {
-            super(writer, contentType);
-            this.bytes = bytes;
-        }
-
-        @Override
-        public byte[] getBytes() {
-            try {
-                writer.finish();
-            } catch (IOException e) {
-                throw new SdkClientException(e);
-            }
-            return bytes.toByteArray();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkJsonGenerator.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkJsonGenerator.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkJsonGenerator.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkJsonGenerator.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,280 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.BinaryUtils;
-import com.amazonaws.util.DateUtils;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-/**
- * Thin wrapper around Jackson's JSON generator.
- */
-@SdkInternalApi
-public class SdkJsonGenerator implements StructuredJsonGenerator {
-
-    /**
-     * Default buffer size for the BAOS. Chosen somewhat arbitrarily. Should be large enough to
-     * prevent frequent resizings but small enough to avoid wasted allocations for small requests.
-     */
-    private static final int DEFAULT_BUFFER_SIZE = 1024;
-
-    /**
-     * Indicates an issue writing JSON content.
-     */
-    public static class JsonGenerationException extends SdkClientException {
-
-        public JsonGenerationException(Throwable t) {
-            super(t);
-        }
-    }
-
-    private final ByteArrayOutputStream baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
-
-    private final JsonGenerator generator;
-
-    private final String contentType;
-
-    public SdkJsonGenerator(JsonFactory factory, String contentType) {
-        try {
-            /**
-             * A {@link JsonGenerator} created is by default enabled with
-             * UTF-8 encoding
-             */
-            this.generator = factory.createGenerator(baos);
-            this.contentType = contentType;
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-    }
-
-    @Override
-    public StructuredJsonGenerator writeStartArray() {
-        try {
-            generator.writeStartArray();
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeEndArray() {
-        try {
-            generator.writeEndArray();
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeNull() {
-        try {
-            generator.writeNull();
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeStartObject() {
-        try {
-            generator.writeStartObject();
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeEndObject() {
-        try {
-            generator.writeEndObject();
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeFieldName(String fieldName) {
-        try {
-            generator.writeFieldName(fieldName);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(String val) {
-        try {
-            generator.writeString(val);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(boolean bool) {
-        try {
-            generator.writeBoolean(bool);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(long val) {
-        try {
-            generator.writeNumber(val);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(double val) {
-        try {
-            generator.writeNumber(val);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(float val) {
-        try {
-            generator.writeNumber(val);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(short val) {
-        try {
-            generator.writeNumber(val);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(int val) {
-        try {
-            generator.writeNumber(val);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(ByteBuffer bytes) {
-        try {
-            generator.writeBinary(BinaryUtils.copyBytesFrom(bytes));
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(Date date) {
-        try {
-            generator.writeNumber(DateUtils.formatServiceSpecificDate(date));
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(BigDecimal value) {
-        try {
-            /**
-             * Note that this is not how the backend represents BigDecimal types. On the wire
-             * it's normally a JSON number but this causes problems with certain JSON implementations
-             * that parse JSON numbers as floating points automatically. (See API-433)
-             */
-            generator.writeString(value.toString());
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    @Override
-    public StructuredJsonGenerator writeValue(BigInteger value) {
-        try {
-            generator.writeNumber(value);
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-        return this;
-    }
-
-    /**
-     * Closes the generator and flushes to write. Must be called when finished writing JSON
-     * content.
-     */
-    private void close() {
-        try {
-            generator.close();
-        } catch (IOException e) {
-            throw new JsonGenerationException(e);
-        }
-    }
-
-    /**
-     * Get the JSON content as a UTF-8 encoded byte array. It is recommended to hold onto the array
-     * reference rather then making repeated calls to this method as a new array will be created
-     * each time.
-     *
-     * @return Array of UTF-8 encoded bytes that make up the generated JSON.
-     */
-    @Override
-    public byte[] getBytes() {
-        close();
-        return baos.toByteArray();
-    }
-
-    @Override
-    public String getContentType() {
-        return contentType;
-    }
-
-    protected JsonGenerator getGenerator() {
-        return generator;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkJsonMarshallerFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkJsonMarshallerFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkJsonMarshallerFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkJsonMarshallerFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Factory interface for creating dependencies needed by generated marshallers for JSON services.
- *
- * @deprecated By {@link com.amazonaws.protocol.ProtocolRequestMarshaller}
- */
-@Deprecated
-@SdkProtectedApi
-public interface SdkJsonMarshallerFactory {
-
-    /**
-     * Returns the {@link SdkJsonGenerator} to be used for marshalling the request.
-     */
-    StructuredJsonGenerator createGenerator();
-
-    /**
-     * @return Content type to send in requests.
-     */
-    String getContentType();
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkJsonProtocolFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkJsonProtocolFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkJsonProtocolFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkJsonProtocolFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,154 +0,0 @@
-/*
- *
- * Copyright (c) 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonWebServiceResponse;
-import com.amazonaws.SDKGlobalConfiguration;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.http.HttpResponseHandler;
-import com.amazonaws.protocol.OperationInfo;
-import com.amazonaws.protocol.Protocol;
-import com.amazonaws.protocol.ProtocolRequestMarshaller;
-import com.amazonaws.transform.JsonErrorUnmarshaller;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.Unmarshaller;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Factory to generate the various JSON protocol handlers and generators depending on the wire protocol to be used for
- * communicating with the AWS service.
- */
-@ThreadSafe
-@SdkProtectedApi
-public class SdkJsonProtocolFactory implements SdkJsonMarshallerFactory {
-
-    private final JsonClientMetadata metadata;
-
-    private final List<JsonErrorUnmarshaller> errorUnmarshallers = new ArrayList<JsonErrorUnmarshaller>();
-
-    public SdkJsonProtocolFactory(JsonClientMetadata metadata) {
-        this.metadata = metadata;
-        createErrorUnmarshallers();
-    }
-
-    @Override
-    public StructuredJsonGenerator createGenerator() {
-        return getSdkFactory().createWriter(getContentType());
-    }
-
-    @Override
-    public String getContentType() {
-        return getContentTypeResolver().resolveContentType(metadata);
-    }
-
-    public <T> ProtocolRequestMarshaller<T> createProtocolMarshaller(OperationInfo operationInfo, T origRequest) {
-        return JsonProtocolMarshallerBuilder.<T>standard()
-                .jsonGenerator(createGenerator(operationInfo))
-                .contentType(getContentType())
-                .operationInfo(operationInfo)
-                .originalRequest(origRequest)
-                .sendExplicitNullForPayload(false)
-                .build();
-    }
-
-    private StructuredJsonGenerator createGenerator(OperationInfo operationInfo) {
-        if (operationInfo.hasPayloadMembers() || operationInfo.protocol() == Protocol.AWS_JSON) {
-            return createGenerator();
-        } else {
-            return StructuredJsonGenerator.NO_OP;
-        }
-    }
-
-    /**
-     * Returns the response handler to be used for handling a successful response.
-     *
-     * @param operationMetadata Additional context information about an operation to create the appropriate response handler.
-     */
-    public <T> HttpResponseHandler<AmazonWebServiceResponse<T>> createResponseHandler(
-            JsonOperationMetadata operationMetadata,
-            Unmarshaller<T, JsonUnmarshallerContext> responseUnmarshaller) {
-        return getSdkFactory().createResponseHandler(operationMetadata, responseUnmarshaller);
-    }
-
-    /**
-     * Creates a response handler for handling a error response (non 2xx response).
-     */
-    public HttpResponseHandler<AmazonServiceException> createErrorResponseHandler(
-            JsonErrorResponseMetadata errorResponsMetadata) {
-        return getSdkFactory().createErrorResponseHandler(errorUnmarshallers, errorResponsMetadata
-                .getCustomErrorCodeFieldName());
-    }
-
-    @SuppressWarnings("unchecked")
-    private void createErrorUnmarshallers() {
-        for (JsonErrorShapeMetadata errorMetadata : metadata.getErrorShapeMetadata()) {
-            errorUnmarshallers.add(new JsonErrorUnmarshaller(
-                    (Class<? extends AmazonServiceException>) errorMetadata.getModeledClass(),
-                    errorMetadata.getErrorCode()));
-
-        }
-        errorUnmarshallers.add(new JsonErrorUnmarshaller(
-                (Class<? extends AmazonServiceException>) metadata.getBaseServiceExceptionClass(),
-                null));
-    }
-
-    /**
-     * @return Instance of {@link SdkStructuredJsonFactory} to use in creating handlers.
-     */
-    private SdkStructuredJsonFactory getSdkFactory() {
-        if (isCborEnabled()) {
-            return SdkStructuredCborFactory.SDK_CBOR_FACTORY;
-        } else if (isIonEnabled()) {
-            return isIonBinaryEnabled()
-                    ? SdkStructuredIonFactory.SDK_ION_BINARY_FACTORY
-                    : SdkStructuredIonFactory.SDK_ION_TEXT_FACTORY;
-        } else {
-            return SdkStructuredPlainJsonFactory.SDK_JSON_FACTORY;
-        }
-    }
-
-    /**
-     * @return Content type resolver implementation to use.
-     */
-    private JsonContentTypeResolver getContentTypeResolver() {
-        if (isCborEnabled()) {
-            return JsonContentTypeResolver.CBOR;
-        } else if (isIonEnabled()) {
-            return isIonBinaryEnabled()
-                    ? JsonContentTypeResolver.ION_BINARY
-                    : JsonContentTypeResolver.ION_TEXT;
-        } else {
-            return JsonContentTypeResolver.JSON;
-        }
-    }
-
-    private boolean isCborEnabled() {
-        return metadata.isSupportsCbor() && !SDKGlobalConfiguration.isCborDisabled();
-    }
-
-    private boolean isIonEnabled() {
-        return metadata.isSupportsIon();
-    }
-
-    boolean isIonBinaryEnabled() {
-        return !SDKGlobalConfiguration.isIonBinaryDisabled();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkStructuredCborFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredCborFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkStructuredCborFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredCborFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,81 +0,0 @@
-/*
- *
- * Copyright (c) 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.BigDecimalCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.BigIntegerCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.BooleanCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.ByteBufferCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.ByteCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.DateCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.DoubleCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.FloatCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.IntegerCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.LongCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.ShortCborUnmarshaller;
-import com.amazonaws.transform.SimpleTypeCborUnmarshallers.StringCborUnmarshaller;
-import com.amazonaws.transform.Unmarshaller;
-import com.amazonaws.util.ImmutableMapParameter;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Map;
-
-/**
- * Creates generators and protocol handlers for CBOR wire format.
- */
-@SdkInternalApi
-class SdkStructuredCborFactory {
-
-    private static final JsonFactory CBOR_FACTORY = new CBORFactory();
-
-    /**
-     * cbor unmarshallers for scalar types.
-     */
-    private static final Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> CBOR_SCALAR_UNMARSHALLERS =
-            new ImmutableMapParameter.Builder<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>>()
-            .put(String.class, StringCborUnmarshaller.getInstance())
-            .put(Double.class, DoubleCborUnmarshaller.getInstance())
-            .put(Integer.class, IntegerCborUnmarshaller.getInstance())
-            .put(BigInteger.class, BigIntegerCborUnmarshaller.getInstance())
-            .put(BigDecimal.class, BigDecimalCborUnmarshaller.getInstance())
-            .put(Boolean.class, BooleanCborUnmarshaller.getInstance())
-            .put(Float.class, FloatCborUnmarshaller.getInstance())
-            .put(Long.class, LongCborUnmarshaller.getInstance())
-            .put(Byte.class, ByteCborUnmarshaller.getInstance())
-            .put(Date.class, DateCborUnmarshaller.getInstance())
-            .put(ByteBuffer.class, ByteBufferCborUnmarshaller.getInstance())
-            .put(Short.class, ShortCborUnmarshaller.getInstance()).build();
-
-    public static final SdkStructuredJsonFactory SDK_CBOR_FACTORY = new SdkStructuredJsonFactoryImpl(
-            CBOR_FACTORY, CBOR_SCALAR_UNMARSHALLERS,
-            Collections.<JsonUnmarshallerContext.UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>>emptyMap()) {
-        @Override
-        protected StructuredJsonGenerator createWriter(JsonFactory jsonFactory,
-                                                       String contentType) {
-            return new SdkCborGenerator(jsonFactory, contentType);
-        }
-    };
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkStructuredIonFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredIonFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkStructuredIonFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredIonFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,95 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.internal.http.CompositeErrorCodeParser;
-import com.amazonaws.internal.http.ErrorCodeParser;
-import com.amazonaws.internal.http.IonErrorCodeParser;
-import com.amazonaws.internal.http.JsonErrorCodeParser;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.BigDecimalIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.BigIntegerIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.BooleanIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.ByteBufferIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.ByteIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.DateIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.DoubleIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.FloatIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.IntegerIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.LongIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.ShortIonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeIonUnmarshallers.StringIonUnmarshaller;
-import com.amazonaws.transform.Unmarshaller;
-import com.amazonaws.util.ImmutableMapParameter;
-import com.fasterxml.jackson.core.JsonFactory;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Map;
-import software.amazon.ion.IonSystem;
-import software.amazon.ion.system.IonBinaryWriterBuilder;
-import software.amazon.ion.system.IonSystemBuilder;
-import software.amazon.ion.system.IonTextWriterBuilder;
-import software.amazon.ion.system.IonWriterBuilder;
-
-@SdkInternalApi
-class SdkStructuredIonFactory extends SdkStructuredJsonFactoryImpl {
-    private static final IonSystem ION_SYSTEM = IonSystemBuilder.standard().build();
-    private static final JsonFactory JSON_FACTORY = new IonFactory(ION_SYSTEM);
-    private static final Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> UNMARSHALLERS =
-            new ImmutableMapParameter.Builder<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>>()
-            .put(BigDecimal.class, BigDecimalIonUnmarshaller.getInstance())
-            .put(BigInteger.class, BigIntegerIonUnmarshaller.getInstance())
-            .put(Boolean.class, BooleanIonUnmarshaller.getInstance())
-            .put(ByteBuffer.class, ByteBufferIonUnmarshaller.getInstance())
-            .put(Byte.class, ByteIonUnmarshaller.getInstance())
-            .put(Date.class, DateIonUnmarshaller.getInstance())
-            .put(Double.class, DoubleIonUnmarshaller.getInstance())
-            .put(Float.class, FloatIonUnmarshaller.getInstance())
-            .put(Integer.class, IntegerIonUnmarshaller.getInstance())
-            .put(Long.class, LongIonUnmarshaller.getInstance())
-            .put(Short.class, ShortIonUnmarshaller.getInstance())
-            .put(String.class, StringIonUnmarshaller.getInstance())
-            .build();
-
-    private static final IonBinaryWriterBuilder BINARY_WRITER_BUILDER = IonBinaryWriterBuilder.standard().immutable();
-    private static final IonTextWriterBuilder TEXT_WRITER_BUILDER = IonTextWriterBuilder.standard().immutable();
-
-    public static final SdkStructuredIonFactory SDK_ION_BINARY_FACTORY = new SdkStructuredIonFactory(BINARY_WRITER_BUILDER);
-    public static final SdkStructuredIonFactory SDK_ION_TEXT_FACTORY = new SdkStructuredIonFactory(TEXT_WRITER_BUILDER);
-
-    private final IonWriterBuilder builder;
-
-    private SdkStructuredIonFactory(IonWriterBuilder builder) {
-        super(JSON_FACTORY, UNMARSHALLERS,
-              Collections.<JsonUnmarshallerContext.UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>>emptyMap());
-        this.builder = builder;
-    }
-
-    @Override
-    protected StructuredJsonGenerator createWriter(JsonFactory jsonFactory, String contentType) {
-        return SdkIonGenerator.create(builder, contentType);
-    }
-
-    @Override
-    protected ErrorCodeParser getErrorCodeParser(String customErrorCodeFieldName) {
-        return new CompositeErrorCodeParser(
-                new IonErrorCodeParser(ION_SYSTEM),
-                new JsonErrorCodeParser(customErrorCodeFieldName));
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactoryImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactoryImpl.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactoryImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactoryImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,79 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.http.JsonErrorResponseHandler;
-import com.amazonaws.http.JsonResponseHandler;
-import com.amazonaws.internal.http.ErrorCodeParser;
-import com.amazonaws.internal.http.JsonErrorCodeParser;
-import com.amazonaws.internal.http.JsonErrorMessageParser;
-import com.amazonaws.transform.JsonErrorUnmarshaller;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.JsonUnmarshallerContext.UnmarshallerType;
-import com.amazonaws.transform.Unmarshaller;
-import com.fasterxml.jackson.core.JsonFactory;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Generic implementation of a structured JSON factory that is pluggable for different variants of
- * JSON. See {@link SdkStructuredPlainJsonFactory#SDK_JSON_FACTORY} and {@link
- * SdkStructuredCborFactory#SDK_CBOR_FACTORY}.
- */
-public abstract class SdkStructuredJsonFactoryImpl implements SdkStructuredJsonFactory {
-
-    private final JsonFactory jsonFactory;
-    private final Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> unmarshallers;
-    private final Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customTypeMarshallers;
-
-    public SdkStructuredJsonFactoryImpl(JsonFactory jsonFactory,
-                                        Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> unmarshallers,
-                                        Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customTypeMarshallers) {
-        this.jsonFactory = jsonFactory;
-        this.unmarshallers = unmarshallers;
-        this.customTypeMarshallers = customTypeMarshallers;
-    }
-
-    @Override
-    public StructuredJsonGenerator createWriter(String contentType) {
-        return createWriter(jsonFactory, contentType);
-    }
-
-    protected abstract StructuredJsonGenerator createWriter(JsonFactory jsonFactory,
-                                                            String contentType);
-
-    @Override
-    public <T> JsonResponseHandler<T> createResponseHandler(JsonOperationMetadata operationMetadata,
-                                                            Unmarshaller<T, JsonUnmarshallerContext> responseUnmarshaller) {
-        return new JsonResponseHandler(responseUnmarshaller, unmarshallers, customTypeMarshallers, jsonFactory,
-                                       operationMetadata.isHasStreamingSuccessResponse(),
-                                       operationMetadata.isPayloadJson());
-    }
-
-    @Override
-    public JsonErrorResponseHandler createErrorResponseHandler(
-            final List<JsonErrorUnmarshaller> errorUnmarshallers, String customErrorCodeFieldName) {
-        return new JsonErrorResponseHandler(errorUnmarshallers,
-                                            getErrorCodeParser(customErrorCodeFieldName),
-                                            JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER,
-                                            jsonFactory);
-    }
-
-    protected ErrorCodeParser getErrorCodeParser(String customErrorCodeFieldName) {
-        return new JsonErrorCodeParser(customErrorCodeFieldName);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredJsonFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.http.JsonErrorResponseHandler;
-import com.amazonaws.http.JsonResponseHandler;
-import com.amazonaws.transform.JsonErrorUnmarshaller;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.Unmarshaller;
-
-import java.util.List;
-
-/**
- * Common interface for creating generators (writers) and protocol handlers for JSON like protocols.
- * Current implementations include {@link SdkStructuredPlainJsonFactory} and {@link
- * SdkStructuredCborFactory}
- */
-@SdkProtectedApi
-public interface SdkStructuredJsonFactory {
-
-    /**
-     * Returns the {@link StructuredJsonGenerator} to be used for marshalling the request.
-     *
-     * @param contentType Content type to send for requests.
-     */
-    StructuredJsonGenerator createWriter(String contentType);
-
-    /**
-     * Returns the response handler to be used for handling a successfull response.
-     *
-     * @param operationMetadata Additional context information about an operation to create the
-     *                          appropriate response handler.
-     */
-    <T> JsonResponseHandler<T> createResponseHandler(JsonOperationMetadata operationMetadata,
-                                                     Unmarshaller<T, JsonUnmarshallerContext> responseUnmarshaller);
-
-    /**
-     * Returns the error response handler for handling a error response.
-     *
-     * @param errorUnmarshallers Response unmarshallers to unamrshall the error responses.
-     */
-    JsonErrorResponseHandler createErrorResponseHandler(
-            List<JsonErrorUnmarshaller> errorUnmarshallers, String customErrorCodeFieldName);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/SdkStructuredPlainJsonFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredPlainJsonFactory.java
--- ./src/main/java/com/amazonaws/protocol/json/SdkStructuredPlainJsonFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/SdkStructuredPlainJsonFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,91 +0,0 @@
-/*
- *
- * Copyright (c) 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.transform.JsonUnmarshallerContext;
-import com.amazonaws.transform.JsonUnmarshallerContext.UnmarshallerType;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.BigDecimalJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.BigIntegerJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.BooleanJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.ByteBufferJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.ByteJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.CharacterJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.DateJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.DoubleJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.FloatJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.IntegerJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.JsonValueStringUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.LongJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.ShortJsonUnmarshaller;
-import com.amazonaws.transform.SimpleTypeJsonUnmarshallers.StringJsonUnmarshaller;
-import com.amazonaws.transform.Unmarshaller;
-import com.amazonaws.util.ImmutableMapParameter;
-import com.fasterxml.jackson.core.JsonFactory;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-import java.util.Map;
-
-/**
- * Creates generators and protocol handlers for plain text JSON wire format.
- */
-@SdkProtectedApi
-public class SdkStructuredPlainJsonFactory {
-
-    /**
-     * Recommended to share JsonFactory instances per http://wiki.fasterxml
-     * .com/JacksonBestPracticesPerformance
-     */
-    public static final JsonFactory JSON_FACTORY = new JsonFactory();
-
-    @SdkTestInternalApi
-    public static final Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> JSON_SCALAR_UNMARSHALLERS =
-            new ImmutableMapParameter.Builder<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>>()
-            .put(String.class, StringJsonUnmarshaller.getInstance())
-            .put(Double.class, DoubleJsonUnmarshaller.getInstance())
-            .put(Integer.class, IntegerJsonUnmarshaller.getInstance())
-            .put(BigInteger.class, BigIntegerJsonUnmarshaller.getInstance())
-            .put(BigDecimal.class, BigDecimalJsonUnmarshaller.getInstance())
-            .put(Boolean.class, BooleanJsonUnmarshaller.getInstance())
-            .put(Float.class, FloatJsonUnmarshaller.getInstance())
-            .put(Long.class, LongJsonUnmarshaller.getInstance())
-            .put(Byte.class, ByteJsonUnmarshaller.getInstance())
-            .put(Date.class, DateJsonUnmarshaller.getInstance())
-            .put(ByteBuffer.class, ByteBufferJsonUnmarshaller.getInstance())
-            .put(Character.class, CharacterJsonUnmarshaller.getInstance())
-            .put(Short.class, ShortJsonUnmarshaller.getInstance()).build();
-
-    @SdkTestInternalApi
-    public static final Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> JSON_CUSTOM_TYPE_UNMARSHALLERS =
-            new ImmutableMapParameter.Builder<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>>()
-                    .put(UnmarshallerType.JSON_VALUE, JsonValueStringUnmarshaller.getInstance())
-                    .build();
-
-    public static final SdkStructuredJsonFactory SDK_JSON_FACTORY = new SdkStructuredJsonFactoryImpl(
-            JSON_FACTORY, JSON_SCALAR_UNMARSHALLERS, JSON_CUSTOM_TYPE_UNMARSHALLERS) {
-        @Override
-        protected StructuredJsonGenerator createWriter(JsonFactory jsonFactory,
-                                                       String contentType) {
-            return new SdkJsonGenerator(jsonFactory, contentType);
-        }
-    };
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/StructuredJsonGenerator.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/StructuredJsonGenerator.java
--- ./src/main/java/com/amazonaws/protocol/json/StructuredJsonGenerator.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/StructuredJsonGenerator.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,177 +0,0 @@
-/*
- *
- * Copyright (c) 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- *
- */
-
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-/**
- * Interface for generating a JSON
- */
-@SdkProtectedApi
-public interface StructuredJsonGenerator {
-
-    /**
-     * No-op implementation that ignores all calls and returns empty bytes from getBytes.
-     */
-    StructuredJsonGenerator NO_OP = new StructuredJsonGenerator() {
-
-        private final byte[] EMPTY_BYTES = new byte[0];
-
-        @Override
-        public StructuredJsonGenerator writeStartArray() {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeEndArray() {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeNull() {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeStartObject() {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeEndObject() {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeFieldName(String fieldName) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(String val) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(boolean bool) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(long val) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(double val) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(float val) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(short val) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(int val) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(ByteBuffer bytes) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(Date date) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(BigDecimal value) {
-            return this;
-        }
-
-        @Override
-        public StructuredJsonGenerator writeValue(BigInteger value) {
-            return this;
-        }
-
-        @Override
-        public byte[] getBytes() {
-            return EMPTY_BYTES;
-        }
-
-        @Override
-        public String getContentType() {
-            return null;
-        }
-    };
-
-    StructuredJsonGenerator writeStartArray();
-
-    StructuredJsonGenerator writeEndArray();
-
-    StructuredJsonGenerator writeNull();
-
-    StructuredJsonGenerator writeStartObject();
-
-    StructuredJsonGenerator writeEndObject();
-
-    StructuredJsonGenerator writeFieldName(String fieldName);
-
-    StructuredJsonGenerator writeValue(String val);
-
-    StructuredJsonGenerator writeValue(boolean bool);
-
-    StructuredJsonGenerator writeValue(long val);
-
-    StructuredJsonGenerator writeValue(double val);
-
-    StructuredJsonGenerator writeValue(float val);
-
-    StructuredJsonGenerator writeValue(short val);
-
-    StructuredJsonGenerator writeValue(int val);
-
-    StructuredJsonGenerator writeValue(ByteBuffer bytes);
-
-    StructuredJsonGenerator writeValue(Date date);
-
-    StructuredJsonGenerator writeValue(BigDecimal value);
-
-    StructuredJsonGenerator writeValue(BigInteger value);
-
-    byte[] getBytes();
-
-    /**
-     * New clients use {@link SdkJsonProtocolFactory#getContentType()}.
-     */
-    @Deprecated
-    String getContentType();
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/json/StructuredJsonMarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/StructuredJsonMarshaller.java
--- ./src/main/java/com/amazonaws/protocol/json/StructuredJsonMarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/json/StructuredJsonMarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,35 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.protocol.json;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Interface to marshall an object to the JSON payload using a {@link StructuredJsonGenerator}.
- *
- * @param <T> Type of object to marshall.
- */
-@SdkProtectedApi
-public interface StructuredJsonMarshaller<T> {
-
-    /**
-     * Marshalls the value using the {@link StructuredJsonGenerator}.
-     *
-     * @param val           Object to marshall.
-     * @param jsonGenerator {@link StructuredJsonGenerator} with methods to write various types to the JSON document.
-     */
-    void marshall(T val, StructuredJsonGenerator jsonGenerator);
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/MarshallingInfo.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/MarshallingInfo.java
--- ./src/main/java/com/amazonaws/protocol/MarshallingInfo.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/MarshallingInfo.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,146 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Metadata about the marshalling requirements of a given member. Includes things like where to put the
- * data (payload, query, etc), the location name it's bound to (JSON field name, query param name, etc)
- * and additional directives about how to transform it (i.e. is it binary data, should it be auto generated, etc).
- */
-@SdkProtectedApi
-public class MarshallingInfo<T> {
-
-    private final MarshallingType<T> marshallingType;
-    private final String marshallLocationName;
-    private final MarshallLocation marshallLocation;
-    private final boolean isExplicitPayloadMember;
-    private final boolean isBinary;
-    private final DefaultValueSupplier<T> defaultValueSupplier;
-
-    private MarshallingInfo(Builder<T> builder) {
-        this.marshallingType = builder.marshallingType;
-        this.marshallLocationName = builder.marshallLocationName;
-        this.marshallLocation = builder.marshallLocation;
-        this.isExplicitPayloadMember = builder.isExplicitPayloadMember;
-        this.isBinary = builder.isBinary;
-        this.defaultValueSupplier = builder.defaultValueSupplier;
-    }
-
-    /**
-     * @return MarshallingType for this member.
-     */
-    public MarshallingType<T> marshallingType() {
-        return marshallingType;
-    }
-
-    /**
-     * @return Marshall location name. This may represent different things depending on where the data is meant to be marshalled
-     * to. For data bound to the payload, this may be the JSON field name, for data bound to the query params this will be the
-     * parameter name, for data bound to the path this will be the value of the path placeholder to replace in the request URI.
-     * Note that it may be null for explicit payload members.
-     */
-    public String marshallLocationName() {
-        return marshallLocationName;
-    }
-
-    /**
-     * @return Where the data should be marshalled to.
-     */
-    public MarshallLocation marshallLocation() {
-        return marshallLocation;
-    }
-
-    /**
-     * @return True if the member is explicitly bound to the payload. Applicable only for RESTFUL services.
-     */
-    public boolean isExplicitPayloadMember() {
-        return isExplicitPayloadMember;
-    }
-
-    /**
-     * @return True if the payload member is binary data (i.e. a {@link java.nio.ByteBuffer} or {@link java.io.InputStream} and
-     * should be sent as the request content. This is not true when binary data is bound to a member of the JSON payload since it
-     * will be base64 encoded as a string.
-     */
-    public boolean isBinary() {
-        return isBinary;
-    }
-
-    /**
-     * @return Optional supplier of default value if the value to marshall is null.
-     */
-    public DefaultValueSupplier<T> defaultValueSupplier() {
-        return defaultValueSupplier;
-    }
-
-    /**
-     * @return Builder instance to construct a {@link MarshallingInfo}.
-     */
-    public static <T> Builder<T> builder(MarshallingType<T> marshallingType) {
-        return new Builder<T>(marshallingType);
-    }
-
-    /**
-     * Builder for a {@link MarshallingInfo}.
-     */
-    public static final class Builder<T> {
-
-        private final MarshallingType<T> marshallingType;
-        private String marshallLocationName;
-        private MarshallLocation marshallLocation;
-        private boolean isExplicitPayloadMember;
-        private boolean isBinary;
-        private DefaultValueSupplier<T> defaultValueSupplier;
-
-        private Builder(MarshallingType<T> marshallingType) {
-            this.marshallingType = marshallingType;
-        }
-
-        public Builder<T> marshallLocationName(String marshallLocationName) {
-            this.marshallLocationName = marshallLocationName;
-            return this;
-        }
-
-        public Builder<T> marshallLocation(MarshallLocation marshallLocation) {
-            this.marshallLocation = marshallLocation;
-            return this;
-        }
-
-        public Builder<T> isExplicitPayloadMember(boolean isExplicitPayloadMember) {
-            this.isExplicitPayloadMember = isExplicitPayloadMember;
-            return this;
-        }
-
-        public Builder<T> isBinary(boolean isBinary) {
-            this.isBinary = isBinary;
-            return this;
-        }
-
-        public Builder<T> defaultValueSupplier(DefaultValueSupplier<T> defaultValueSupplier) {
-            this.defaultValueSupplier = defaultValueSupplier;
-            return this;
-        }
-
-        /**
-         * @return An immutable {@link MarshallingInfo} object.
-         */
-        public MarshallingInfo<T> build() {
-            return new MarshallingInfo<T>(this);
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/MarshallingType.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/MarshallingType.java
--- ./src/main/java/com/amazonaws/protocol/MarshallingType.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/MarshallingType.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,79 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.nio.ByteBuffer;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Represents the various types supported for marshalling.
- *
- * @param <T> Java type bound to the marshalling type.
- */
-@SdkProtectedApi
-public interface MarshallingType<T> {
-    /**
-     * Determine whether this marshalling type is the default marshaller for the provided class. This is used to automatically
-     * determine the marshaller to be used in the contents of lists or maps.
-     */
-    boolean isDefaultMarshallerForType(Class<?> type);
-
-    /**
-     * Used when a value is null (and thus type can't be determined).
-     */
-    MarshallingType<Void> NULL = new DefaultMarshallingType<Void>(Void.class);
-
-    MarshallingType<String> STRING = new DefaultMarshallingType<String>(String.class);
-
-    MarshallingType<Integer> INTEGER = new DefaultMarshallingType<Integer>(Integer.class);
-
-    MarshallingType<Long> LONG = new DefaultMarshallingType<Long>(Long.class);
-
-    MarshallingType<Float> FLOAT = new DefaultMarshallingType<Float>(Float.class);
-
-    MarshallingType<Double> DOUBLE = new DefaultMarshallingType<Double>(Double.class);
-
-    MarshallingType<BigDecimal> BIG_DECIMAL = new DefaultMarshallingType<BigDecimal>(BigDecimal.class);
-
-    MarshallingType<Boolean> BOOLEAN = new DefaultMarshallingType<Boolean>(Boolean.class);
-
-    MarshallingType<Date> DATE = new DefaultMarshallingType<Date>(Date.class);
-
-    MarshallingType<ByteBuffer> BYTE_BUFFER = new DefaultMarshallingType<ByteBuffer>(ByteBuffer.class);
-
-    MarshallingType<InputStream> STREAM = new DefaultMarshallingType<InputStream>(InputStream.class);
-
-    MarshallingType<StructuredPojo> STRUCTURED = new DefaultMarshallingType<StructuredPojo>(StructuredPojo.class);
-
-    MarshallingType<List> LIST = new DefaultMarshallingType<List>(List.class);
-
-    MarshallingType<Map> MAP = new DefaultMarshallingType<Map>(Map.class);
-
-    /**
-     * A serializer for strings that should be base-64 encoded when they are sent to AWS.
-     */
-    MarshallingType<String> JSON_VALUE = new MarshallingType<String>() {
-        @Override
-        public boolean isDefaultMarshallerForType(Class<?> type) {
-            return false;
-        }
-    };
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/MarshallLocation.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/MarshallLocation.java
--- ./src/main/java/com/amazonaws/protocol/MarshallLocation.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/MarshallLocation.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,51 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Enum representing the various locations data can be marshalled to.
- */
-@SdkProtectedApi
-public enum MarshallLocation {
-
-    /**
-     * Payload of the request (format depends on the protocol/content-type)
-     */
-    PAYLOAD,
-
-    /**
-     * Add as a query parameter.
-     */
-    QUERY_PARAM,
-
-    /**
-     * HTTP header.
-     */
-    HEADER,
-
-    /**
-     * Replace the placeholder in the request URI (non-greedy).
-     */
-    PATH,
-
-    /**
-     * Replace the placeholder in the request URI (greedy). This location is really the same as {@link #PATH},
-     * the only difference is whether it's URL encoded or not. Members bound to the {@link #PATH} will be URL
-     * encoded before replacing, members bound to {@link #GREEDY_PATH} will not be URL encoded.
-     */
-    GREEDY_PATH
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/OperationInfo.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/OperationInfo.java
--- ./src/main/java/com/amazonaws/protocol/OperationInfo.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/OperationInfo.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,166 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.Request;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.http.HttpMethodName;
-
-
-/**
- * Static information about an API operation used to marshall it correctly.
- */
-@SdkProtectedApi
-public class OperationInfo {
-
-    private final Protocol protocol;
-    private final String requestUri;
-    private final HttpMethodName httpMethodName;
-    private final String operationIdentifier;
-    private final String serviceName;
-    private final boolean hasExplicitPayloadMember;
-    private final boolean hasPayloadMembers;
-
-    private OperationInfo(Builder builder) {
-        this.protocol = builder.protocol;
-        this.requestUri = builder.requestUri;
-        this.httpMethodName = builder.httpMethodName;
-        this.operationIdentifier = builder.operationIdentifier;
-        this.serviceName = builder.serviceName;
-        this.hasExplicitPayloadMember = builder.hasExplicitPayloadMember;
-        this.hasPayloadMembers = builder.hasPayloadMembers;
-    }
-
-    /**
-     * @return The protocol of the client. Gives hints to the marshaller on how things should be transformed.
-     */
-    public Protocol protocol() {
-        return protocol;
-    }
-
-    /**
-     * @return Request URI for operation (may contain placeholders for members bound to the uri).
-     */
-    public String requestUri() {
-        return requestUri;
-    }
-
-    /**
-     * @return HTTP Method that should be used when sending the request.
-     */
-    public HttpMethodName httpMethodName() {
-        return httpMethodName;
-    }
-
-    /**
-     * @return Identifer for the operation/API being invoked. This is used for RPC based protocols that
-     * need to identify which action is being taken. For Query/EC2 protocol this is sent as the 'Action' query
-     * parameter, for JSON RPC this is sent as the 'X-Amz-Target' header.
-     */
-    public String operationIdentifier() {
-        return operationIdentifier;
-    }
-
-    /**
-     * @return Display name for the service. Mainly used for the metrics system but is also available on the {@link Request}
-     * object (to do something in a {@link com.amazonaws.handlers.RequestHandler2} for example). This is usually the service
-     * interface name but may be customized at generation time ('AmazonDynamoDBv2' for example).
-     */
-    public String serviceName() {
-        return serviceName;
-    }
-
-    /**
-     * @return True if the operation has a member that's explicitly marked as the payload. False otherwise. (Applicable only to
-     * RESTUL protocols).
-     */
-    public boolean hasExplicitPayloadMember() {
-        return hasExplicitPayloadMember;
-    }
-
-    /**
-     * @return True if the operation has members bound to the payload. Some requests (especially GET and DELETE) may not
-     * have any members bound to the payload. (Applicable only to RESTFUL protocols).
-     */
-    public boolean hasPayloadMembers() {
-        return hasPayloadMembers;
-    }
-
-    /**
-     * @return Builder instance to construct a {@link OperationInfo}.
-     */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Builder for a {@link OperationInfo}.
-     */
-    public static final class Builder {
-
-        private Protocol protocol;
-        private String requestUri;
-        private HttpMethodName httpMethodName;
-        private String operationIdentifier;
-        private String serviceName;
-        private boolean hasExplicitPayloadMember;
-        private boolean hasPayloadMembers;
-
-        public Builder protocol(Protocol protocol) {
-            this.protocol = protocol;
-            return this;
-        }
-
-        public Builder requestUri(String requestUri) {
-            this.requestUri = requestUri;
-            return this;
-        }
-
-        public Builder httpMethodName(HttpMethodName httpMethodName) {
-            this.httpMethodName = httpMethodName;
-            return this;
-        }
-
-        public Builder operationIdentifier(String operationIdentifier) {
-            this.operationIdentifier = operationIdentifier;
-            return this;
-        }
-
-        public Builder serviceName(String serviceName) {
-            this.serviceName = serviceName;
-            return this;
-        }
-
-        public Builder hasExplicitPayloadMember(boolean hasExplicitPayloadMember) {
-            this.hasExplicitPayloadMember = hasExplicitPayloadMember;
-            return this;
-        }
-
-        public Builder hasPayloadMembers(boolean hasPayloadMembers) {
-            this.hasPayloadMembers = hasPayloadMembers;
-            return this;
-        }
-
-        private Builder() {
-        }
-
-        /**
-         * @return An immutable {@link OperationInfo} object.
-         */
-        public OperationInfo build() {
-            return new OperationInfo(this);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/Protocol.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/Protocol.java
--- ./src/main/java/com/amazonaws/protocol/Protocol.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/Protocol.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-/**
- * Supported protocols for the new marshalling style. Currently only includes JSON based services.
- */
-public enum Protocol {
-
-    /**
-     * RPC protocol that sends all data in the payload as JSON and sends the X-Amz-Target header to indicate the
-     * operation to invoke.
-     */
-    AWS_JSON,
-
-    /**
-     * Protocol that supports RESTful bindings. Members can be bound to the headers, query params, path, or payload. Supports
-     * binary and streaming data. Operation is identified by HTTP verb and resource path combination.
-     */
-    REST_JSON,
-
-    /**
-     * A variation of REST_JSON for externally generated, API Gateway clients.
-     */
-    API_GATEWAY
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/ProtocolMarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/ProtocolMarshaller.java
--- ./src/main/java/com/amazonaws/protocol/ProtocolMarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/ProtocolMarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Interface used by generated marshallers to marshall a Java POJO.
- */
-@SdkProtectedApi
-public interface ProtocolMarshaller {
-
-    /**
-     * Marshalls the value into the appropriate location based on the {@link MarshallingInfo} metadata.
-     *
-     * @param val             Value to marshall. May be null if the location allows it (for example, members bound to the path
-     *                        must never be null or empty).
-     * @param marshallingInfo Metadata about how and where to marshall the data. Must not be null.
-     * @throws com.amazonaws.SdkClientException If invalid parameters or combination of parameters are provided (I.E. null value
-     *                                          provided for member bound to the path).
-     */
-    <T> void marshall(T val, MarshallingInfo<T> marshallingInfo) throws SdkClientException;
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/ProtocolRequestMarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/ProtocolRequestMarshaller.java
--- ./src/main/java/com/amazonaws/protocol/ProtocolRequestMarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/ProtocolRequestMarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.Request;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Interface used by generated marshallers to transform a Java POJO in a {@link Request} object which represents an HTTP request.
- *
- * <p><b>Example Usage:</b></p>
- * <pre>
- * {@code
- * ProtocolRequestMarshaller<FooRequest> = createProtocolMarshaller(...);
- * protocolMarshaller.startMarshalling();
- * protocolMarshaller.marshall(obj, marshallingInfo);
- * Request<FooRequest> marshalledRequest = protocolMarshaller.finishMarshalling();
- * }
- * </pre>
- *
- * @param <OrigRequest> Type of the original request object.
- */
-@SdkProtectedApi
-public interface ProtocolRequestMarshaller<OrigRequest> extends ProtocolMarshaller {
-
-    /**
-     * Hook to perform an initialization that needs to happen at the start of marshalling. Must be called before
-     * any call to {@link #marshall(Object, MarshallingInfo)}.
-     */
-    void startMarshalling();
-
-    /**
-     * Finializes the marshalling and produces a {@link Request} object that can be sent for execution. Must be the last
-     * method called in the marshaller.
-     *
-     * @return Marshalled {@link Request} object.
-     */
-    Request<OrigRequest> finishMarshalling();
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/protocol/StructuredPojo.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/StructuredPojo.java
--- ./src/main/java/com/amazonaws/protocol/StructuredPojo.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/protocol/StructuredPojo.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.protocol;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Interface implemented by model classes so that they may marshaller themselves.
- */
-@SdkProtectedApi
-public interface StructuredPojo {
-
-    /**
-     * Marshalls this structured data using the given {@link ProtocolMarshaller}.
-     *
-     * @param protocolMarshaller Implementation of {@link ProtocolMarshaller} used to marshall this object's data.
-     */
-    void marshall(ProtocolMarshaller protocolMarshaller);
-}
diff -Nau8r ./src/main/java/com/amazonaws/Protocol.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/Protocol.java
--- ./src/main/java/com/amazonaws/Protocol.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/Protocol.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-/**
- * Represents the communication protocol to use when sending requests to AWS.
- * <p>
- * Communication over HTTPS is the default, and is more secure than HTTP, which
- * is why AWS recommends using HTTPS. HTTPS connections can use more system
- * resources because of the extra work to encrypt network traffic, so the option
- * to use HTTP is available in case users need it.
- */
-public enum Protocol {
-
-    /**
-     * HTTP Protocol - Using the HTTP protocol is less secure than HTTPS, but
-     * can slightly reduce the system resources used when communicating with
-     * AWS.
-     */
-    HTTP("http"),
-
-    /**
-     * HTTPS Protocol - Using the HTTPS protocol is more secure than using the
-     * HTTP protocol, but may use slightly more system resources. AWS recommends
-     * using HTTPS for maximize security.
-     */
-    HTTPS("https");
-
-    private final String protocol;
-
-    private Protocol(String protocol) {
-        this.protocol = protocol;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Enum#toString()
-     */
-    @Override
-    public String toString() {
-        return protocol;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/ProxyAuthenticationMethod.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ProxyAuthenticationMethod.java
--- ./src/main/java/com/amazonaws/ProxyAuthenticationMethod.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ProxyAuthenticationMethod.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws;
-
-import java.util.List;
-
-/**
- * Methods by which the SDK can authenticate against an HTTP proxy. These can be configured on a client using
- * {@link ClientConfiguration#setProxyAuthenticationMethods(List)}.
- */
-public enum ProxyAuthenticationMethod {
-    SPNEGO,
-    KERBEROS,
-    NTLM,
-    DIGEST,
-    BASIC
-}
diff -Nau8r ./src/main/java/com/amazonaws/ReadLimitInfo.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ReadLimitInfo.java
--- ./src/main/java/com/amazonaws/ReadLimitInfo.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ReadLimitInfo.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,23 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-public interface ReadLimitInfo {
-    /**
-     * Returns the read limit for mark-and-reset during retries; or -1 if not
-     * available.
-     */
-    public int getReadLimit();
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/AbstractRegionMetadataProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AbstractRegionMetadataProvider.java
--- ./src/main/java/com/amazonaws/regions/AbstractRegionMetadataProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AbstractRegionMetadataProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,59 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import java.net.URI;
-
-
-/**
- * An abstract implementation of {@link RegionMetadataProvider}
- */
-
-public abstract class AbstractRegionMetadataProvider implements
-        RegionMetadataProvider {
-
-    @Override
-    public Region getRegionByEndpoint(String endpoint) {
-        String host = getHost(endpoint);
-
-        for (Region region : getRegions()) {
-            for (String serviceEndpoint :
-                    region.getAvailableEndpoints()) {
-
-                if (host.equals(getHost(serviceEndpoint))) {
-                    return region;
-                }
-            }
-        }
-
-        throw new IllegalArgumentException(
-                "No region found with any service for endpoint " + endpoint);
-    }
-
-    /**
-     * Parse the host portion out of an endpoint (which may or may not
-     * contain a scheme).
-     *
-     * @param endpoint the endpoint to parse
-     * @return the host portion of the endpoint
-     */
-    private static String getHost(final String endpoint) {
-        String host = URI.create(endpoint).getHost();
-        if (host == null) {
-            host = URI.create("http://" + endpoint).getHost();
-        }
-        return host;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/AwsEnvVarOverrideRegionProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsEnvVarOverrideRegionProvider.java
--- ./src/main/java/com/amazonaws/regions/AwsEnvVarOverrideRegionProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsEnvVarOverrideRegionProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,31 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.SdkClientException;
-
-import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_ENV_VAR;
-
-/**
- * Loads region information from the '{@value com.amazonaws.SDKGlobalConfiguration#AWS_REGION_ENV_VAR}'
- * environment variable.
- */
-public class AwsEnvVarOverrideRegionProvider extends AwsRegionProvider {
-
-    @Override
-    public String getRegion() throws SdkClientException {
-        return System.getenv(AWS_REGION_ENV_VAR);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/AwsProfileRegionProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsProfileRegionProvider.java
--- ./src/main/java/com/amazonaws/regions/AwsProfileRegionProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsProfileRegionProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,73 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.auth.profile.internal.AllProfiles;
-import com.amazonaws.auth.profile.internal.AwsProfileNameLoader;
-import com.amazonaws.auth.profile.internal.BasicProfile;
-import com.amazonaws.auth.profile.internal.BasicProfileConfigLoader;
-import com.amazonaws.profile.path.AwsProfileFileLocationProvider;
-import com.amazonaws.util.StringUtils;
-
-import java.io.File;
-
-/**
- * Loads region information from the shared AWS config file. Uses the default profile unless
- * otherwise specified.
- */
-public class AwsProfileRegionProvider extends AwsRegionProvider {
-
-    private final String profileName;
-    private final AwsProfileFileLocationProvider locationProvider;
-    private final BasicProfileConfigLoader profileConfigLoader;
-
-    public AwsProfileRegionProvider() {
-        this(AwsProfileNameLoader.INSTANCE.loadProfileName());
-    }
-
-    public AwsProfileRegionProvider(String profileName) {
-        this(profileName, AwsProfileFileLocationProvider.DEFAULT_CONFIG_LOCATION_PROVIDER,
-             BasicProfileConfigLoader.INSTANCE);
-    }
-
-    @SdkTestInternalApi
-    AwsProfileRegionProvider(String profileName, AwsProfileFileLocationProvider locationProvider,
-                             BasicProfileConfigLoader configLoader) {
-        this.profileName = profileName;
-        this.locationProvider = locationProvider;
-        this.profileConfigLoader = configLoader;
-    }
-
-    @Override
-    public String getRegion() throws SdkClientException {
-        File configFile = locationProvider.getLocation();
-        if (configFile != null && configFile.exists()) {
-            BasicProfile profile = loadProfile(configFile);
-            if (profile != null && !StringUtils.isNullOrEmpty(profile.getRegion())) {
-                return profile.getRegion();
-            }
-        }
-        return null;
-    }
-
-    private BasicProfile loadProfile(File configFile) {
-        final AllProfiles allProfiles = profileConfigLoader.loadProfiles(configFile);
-        return allProfiles.getProfile(profileName);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/AwsRegionProviderChain.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsRegionProviderChain.java
--- ./src/main/java/com/amazonaws/regions/AwsRegionProviderChain.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsRegionProviderChain.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,61 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.auth.AWSCredentialsProviderChain;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Composite {@link AwsRegionProvider} that sequentially delegates to a chain of providers looking
- * for region information.
- */
-public class AwsRegionProviderChain extends AwsRegionProvider {
-
-    private static final Log LOG = LogFactory.getLog(AWSCredentialsProviderChain.class);
-
-    private final List<AwsRegionProvider> providers;
-
-    public AwsRegionProviderChain(AwsRegionProvider... providers) {
-        this.providers = new ArrayList<AwsRegionProvider>(providers.length);
-        Collections.addAll(this.providers, providers);
-    }
-
-    @Override
-    public String getRegion() throws SdkClientException {
-        for (AwsRegionProvider provider : providers) {
-            try {
-                final String region = provider.getRegion();
-                if (region != null) {
-                    return region;
-                }
-            } catch (Exception e) {
-                // Ignore any exceptions and move onto the next provider
-                LOG.debug("Unable to load region from " + provider.toString() +
-                          ": " + e.getMessage());
-            }
-        }
-        // Note: This is a bug in the provider chain. The chain should return null when no region is found according to
-        // the interface, but an exception is thrown  here instead. This class is used in too many places to change now.
-        // TODO: In 2.0, be sure this bug does not carry through.
-        throw new SdkClientException("Unable to load region information from any provider in the chain");
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/AwsRegionProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsRegionProvider.java
--- ./src/main/java/com/amazonaws/regions/AwsRegionProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsRegionProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.SdkClientException;
-
-/**
- * Interface for providing AWS region information. Implementations are free to use any strategy for
- * providing region information.
- */
-public abstract class AwsRegionProvider {
-
-    /**
-     * @return Region name to use or null if region information is not available.
-     */
-    public abstract String getRegion() throws SdkClientException;
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/AwsSystemPropertyRegionProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsSystemPropertyRegionProvider.java
--- ./src/main/java/com/amazonaws/regions/AwsSystemPropertyRegionProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/AwsSystemPropertyRegionProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.SDKGlobalConfiguration;
-import com.amazonaws.SdkClientException;
-
-/**
- * Loads region information from the '{@value com.amazonaws.SDKGlobalConfiguration#AWS_REGION_SYSTEM_PROPERTY}' JVM system
- * property.
- */
-public class AwsSystemPropertyRegionProvider extends AwsRegionProvider {
-
-    @Override
-    public String getRegion() throws SdkClientException {
-        return System.getProperty(SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/DefaultAwsRegionProviderChain.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/DefaultAwsRegionProviderChain.java
--- ./src/main/java/com/amazonaws/regions/DefaultAwsRegionProviderChain.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/DefaultAwsRegionProviderChain.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,28 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-/**
- * Default region provider chain used when no explicit region is supplied to a client builder.
- */
-public class DefaultAwsRegionProviderChain extends AwsRegionProviderChain {
-
-    public DefaultAwsRegionProviderChain() {
-        super(new AwsEnvVarOverrideRegionProvider(),
-              new AwsSystemPropertyRegionProvider(),
-              new AwsProfileRegionProvider(),
-              new InstanceMetadataRegionProvider());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/InMemoryRegionImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/InMemoryRegionImpl.java
--- ./src/main/java/com/amazonaws/regions/InMemoryRegionImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/InMemoryRegionImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,107 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.util.ValidationUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of {@link RegionImpl} that holds all information in memory.
- */
-public class InMemoryRegionImpl implements RegionImpl {
-
-    private static final String DEFAULT_DOMAIN = "amazonaws.com";
-
-    private final String name;
-
-    private final String domain;
-
-    private final Map<String, String> endpoints = new HashMap<String,
-            String>();
-
-    private final List<String> https = new ArrayList<String>();
-
-    private final List<String> http = new ArrayList<String>();
-
-    public InMemoryRegionImpl(String name, String domain) {
-        ValidationUtils.assertNotNull(name, "region name");
-        this.name = name;
-        this.domain = domain == null ? DEFAULT_DOMAIN : domain;
-    }
-
-    public InMemoryRegionImpl addEndpoint(String serviceName, String endpoint) {
-        ValidationUtils.assertNotNull(serviceName, "service name");
-        ValidationUtils.assertNotNull(endpoint, "endpoint");
-
-        endpoints.put(serviceName, endpoint);
-        return this;
-    }
-
-    public InMemoryRegionImpl addHttps(String serviceName) {
-        https.add(serviceName);
-        return this;
-    }
-
-    public InMemoryRegionImpl addHttp(String serviceName) {
-        http.add(serviceName);
-        return this;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public String getDomain() {
-        return domain;
-    }
-
-    @Override
-    public String getPartition() {
-        throw new UnsupportedOperationException("Partition is not available in the in memory implementation");
-    }
-
-    @Override
-    public boolean isServiceSupported(String serviceName) {
-        return endpoints.containsKey(serviceName);
-    }
-
-    @Override
-    public String getServiceEndpoint(String serviceName) {
-        return endpoints.get(serviceName);
-    }
-
-    @Override
-    public boolean hasHttpsEndpoint(String serviceName) {
-        return https.contains(serviceName);
-    }
-
-    @Override
-    public boolean hasHttpEndpoint(String serviceName) {
-        return http.contains(serviceName);
-    }
-
-    @Override
-    public Collection<String> getAvailableEndpoints() {
-        return Collections.unmodifiableCollection(endpoints.values());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/InMemoryRegionsProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/InMemoryRegionsProvider.java
--- ./src/main/java/com/amazonaws/regions/InMemoryRegionsProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/InMemoryRegionsProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,73 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.ValidationUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Region metadata provider that holds all data in memory and returns data
- * from them.
- */
-@SdkInternalApi
-public class InMemoryRegionsProvider extends AbstractRegionMetadataProvider {
-
-    /** list of regions. */
-    private final List<Region> regions;
-
-    public InMemoryRegionsProvider(List<Region> regions) {
-        ValidationUtils.assertNotNull(regions, "regions");
-        this.regions = Collections.unmodifiableList(new ArrayList<Region>
-                (regions));
-    }
-
-    @Override
-    public List<Region> getRegions() {
-        return Collections.unmodifiableList(new ArrayList<Region>(regions));
-    }
-
-    @Override
-    public Region getRegion(String regionName) {
-        for (Region region : regions) {
-            if (region.getName().equals(regionName)) {
-                return region;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<Region> getRegionsForService(String serviceName) {
-        final List<Region> results = new LinkedList<Region>();
-
-        for (Region region : regions) {
-            if (region.isServiceSupported(serviceName)) {
-                results.add(region);
-            }
-        }
-
-        return results;
-    }
-
-    @Override
-    public String toString() {
-        return regions.toString();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/InstanceMetadataRegionProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/InstanceMetadataRegionProvider.java
--- ./src/main/java/com/amazonaws/regions/InstanceMetadataRegionProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/InstanceMetadataRegionProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,65 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.SDKGlobalConfiguration;
-import com.amazonaws.util.EC2MetadataUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Attempts to load region information from the EC2 Metadata service. If the application is not
- * running on EC2 or {@link SDKGlobalConfiguration#isEc2MetadataDisabled()} returns true,
- * this provider will return null.
- */
-public class InstanceMetadataRegionProvider extends AwsRegionProvider {
-
-    private static final Log LOG = LogFactory.getLog(InstanceMetadataRegionProvider.class);
-
-    /**
-     * Cache region as it will not change during the lifetime of the JVM.
-     */
-    private volatile String region;
-
-    /**
-     * @throws AmazonClientException if {@link SDKGlobalConfiguration#isEc2MetadataDisabled()} is true
-     */
-    @Override
-    public String getRegion() {
-        if (SDKGlobalConfiguration.isEc2MetadataDisabled()) {
-            throw new AmazonClientException("AWS_EC2_METADATA_DISABLED is set to true, not loading region from EC2 Instance "
-                                         + "Metadata service");
-        }
-
-        if (region == null) {
-            synchronized (this) {
-                if (region == null) {
-                    this.region = tryDetectRegion();
-                }
-            }
-        }
-        return region;
-    }
-
-    private String tryDetectRegion() {
-        try {
-            return EC2MetadataUtils.getEC2InstanceRegion();
-        } catch (AmazonClientException sce) {
-            LOG.debug("Ignoring failure to retrieve the region: " + sce.getMessage());
-            return null;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/LegacyRegionXmlLoadUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/LegacyRegionXmlLoadUtils.java
--- ./src/main/java/com/amazonaws/regions/LegacyRegionXmlLoadUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/LegacyRegionXmlLoadUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,117 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.RuntimeHttpUtils;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-
-@Deprecated
-@SdkInternalApi
-public class LegacyRegionXmlLoadUtils {
-
-    /**
-     * Loads a set of region metadata by downloading an XML file from the
-     * given URI and parsing it.
-     *
-     * @param uri    the uri of the XML file to parse
-     * @param config configuration for the HTTP client to use to fetch the file
-     * @throws IOException any error while reading data.
-     */
-    public static RegionMetadata load
-    (final URI uri, final ClientConfiguration config) throws
-            IOException {
-
-        return RegionMetadataParser.parse(
-                RuntimeHttpUtils.fetchFile(uri, config));
-    }
-
-    /**
-     * Loads a set of region metadata by parsing the given file.
-     *
-     * @param file the region metadata to load from
-     * @throws IOException any error while reading from file.
-     */
-    public static RegionMetadata load
-    (final File file) throws IOException {
-        return RegionMetadataParser.parse(new BufferedInputStream(new
-                FileInputStream(file)));
-    }
-
-    /**
-     * Loads a set of region metadata from an arbitrary {@code InputStream}
-     * containing an XML file.
-     *
-     * @param stream the stream to load from
-     * @return the loaded region metadata
-     * @throws IOException on error reading from the stream
-     */
-    public static RegionMetadata load
-    (final InputStream stream) throws IOException {
-
-        return RegionMetadataParser.parse(stream);
-    }
-
-    /**
-     * Loads a set of region metadata from an XML file stored as a resource of
-     * the classloader used to load the given class.
-     *
-     * @param clazz the class to use as a base for the resource
-     * @param name  the path to the resource, relative to the given class
-     * @return the parsed region metadata
-     * @throws IOException if the resource is not found or cannot be parsed
-     */
-    public static RegionMetadata load(
-            final Class<?> clazz,
-            final String name) throws IOException {
-
-        InputStream stream = clazz.getResourceAsStream(name);
-        if (stream == null) {
-            throw new FileNotFoundException(
-                    "No resource '" + name + "' found.");
-        }
-
-        return load(stream);
-    }
-
-    /**
-     * Loads a set of region metadata from an XML file stored as a resource
-     * of the given classloader.
-     *
-     * @param classLoader the class loader to load the resource from
-     * @param name        the path to the resource
-     * @return the parsed region metadata
-     * @throws IOException if the resource is not found or cannot be parsed
-     */
-    public static RegionMetadata load(
-            final ClassLoader classLoader,
-            final String name) throws IOException {
-
-        InputStream stream = classLoader.getResourceAsStream(name);
-        if (stream == null) {
-            throw new FileNotFoundException(
-                    "No resource '" + name + "' found.");
-        }
-        return load(stream);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/LegacyRegionXmlMetadataBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/LegacyRegionXmlMetadataBuilder.java
--- ./src/main/java/com/amazonaws/regions/LegacyRegionXmlMetadataBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/LegacyRegionXmlMetadataBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,107 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.SDKGlobalConfiguration;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.internal.config.Builder;
-import com.amazonaws.util.IOUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A region metadata builder that loads the data by looking at all the
- * legacy metadata locations.
- */
-@SdkInternalApi
-public class LegacyRegionXmlMetadataBuilder implements Builder<RegionMetadata> {
-
-    private static final String REGIONS_FILE_OVERRIDE =
-            SDKGlobalConfiguration.REGIONS_FILE_OVERRIDE_SYSTEM_PROPERTY;
-
-    private static final String OVERRIDE_ENDPOINTS_RESOURCE_PATH =
-            "/com/amazonaws/regions/override/regions.xml";
-
-    private static final Log LOG = LogFactory.getLog(LegacyRegionXmlMetadataBuilder.class);
-
-    @Override
-    public RegionMetadata build() {
-        return loadOverrideMetadataIfExists();
-    }
-
-    private RegionMetadata loadOverrideMetadataIfExists() {
-        RegionMetadata metadata = loadFromSystemProperty();
-
-        if (metadata == null) {
-            InputStream override = RegionUtils.class
-                    .getResourceAsStream(OVERRIDE_ENDPOINTS_RESOURCE_PATH);
-            if (override != null) {
-                metadata = loadFromStream(override);
-                IOUtils.closeQuietly(override, LOG);
-            }
-        }
-
-        return metadata;
-    }
-
-    /**
-     * Loads region metadata from file location specified in
-     * {@link #REGIONS_FILE_OVERRIDE} property.
-     * Returns null if no such property exists.
-     *
-     * @throws SdkClientException if any error occurs while loading the
-     *                               metadata file.
-     */
-    private RegionMetadata loadFromSystemProperty() {
-        final String overrideFilePath = System.getProperty
-                (REGIONS_FILE_OVERRIDE);
-
-        if (overrideFilePath != null) {
-            try {
-                return LegacyRegionXmlLoadUtils.load(new File
-                        (overrideFilePath));
-            } catch (IOException exception) {
-                throw new SdkClientException(
-                        "Error parsing region metadata from " + overrideFilePath,
-                        exception);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Loads region metadata from file location specified in
-     * {@link #REGIONS_FILE_OVERRIDE} property.
-     * Returns null if no such property exists.
-     *
-     * @throws SdkClientException if any error occurs while loading the
-     *                               metadata file.
-     */
-    private RegionMetadata loadFromStream(final InputStream stream) {
-        try {
-            return LegacyRegionXmlLoadUtils.load(stream);
-        } catch (IOException exception) {
-            throw new SdkClientException(
-                    "Error parsing region metadata from input stream",
-                    exception);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/RegionImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionImpl.java
--- ./src/main/java/com/amazonaws/regions/RegionImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,95 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-import java.util.Collection;
-
-/**
- * Interface for an region implementation.
- */
-@SdkInternalApi
-public interface RegionImpl {
-
-    /**
-     * The unique system ID for this region; ex: &quot;us-east-1&quot;.
-     *
-     * @return The unique system ID for this region.
-     */
-    String getName();
-
-    /**
-     * Returns the domain for this region; ex: &quot;amazonaws.com&quot;.
-     *
-     * @return The domain for this region.
-     */
-    String getDomain();
-
-    /**
-     * Returns the partition this region is in. I.E. 'aws' or 'aws-cn'
-     *
-     * @return The partition this region is in.
-     */
-    String getPartition();
-
-    /**
-     * Returns whether the given service is supported in this region.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    boolean isServiceSupported(String serviceName);
-
-    /**
-     * Returns the endpoint for the service given.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    String getServiceEndpoint(String serviceName);
-
-    /**
-     * Returns whether the given service support the https protocol in this region.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    boolean hasHttpEndpoint(String serviceName);
-
-    /**
-     * Returns whether the given service support the http protocol in this region.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    boolean hasHttpsEndpoint(String serviceName);
-
-    /**
-     * Returns an immutable collection of all the endpoints available in the
-     * region
-     * metadata.
-     */
-    Collection<String> getAvailableEndpoints();
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/Region.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/Region.java
--- ./src/main/java/com/amazonaws/regions/Region.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/Region.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,189 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.AmazonWebServiceClient;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.util.ValidationUtils;
-
-import java.lang.reflect.Constructor;
-import java.util.Collection;
-
-/**
- * Metadata for an AWS region, including its name and what services
- * are available in it.
- */
-public class Region {
-
-    private final RegionImpl regionImpl;
-
-    public Region(RegionImpl regionImpl) {
-        ValidationUtils.assertNotNull(regionImpl, "region implementation");
-        this.regionImpl = regionImpl;
-    }
-
-    /**
-     * Returns the region with the id given, or null if it cannot be found in
-     * the current regions.xml file.
-     */
-    public static Region getRegion(Regions region) {
-        return RegionUtils.getRegion(region.getName());
-    }
-
-    /**
-     * The unique system ID for this region; ex: &quot;us-east-1&quot;.
-     *
-     * @return The unique system ID for this region.
-     */
-    public String getName() {
-        return regionImpl.getName();
-    }
-
-    /**
-     * Returns the domain for this region; ex: &quot;amazonaws.com&quot;.
-     *
-     * @return The domain for this region.
-     */
-    public String getDomain() {
-        return regionImpl.getDomain();
-    }
-
-    /**
-     * Returns the partition this region is in. I.E. 'aws' or 'aws-cn'
-     *
-     * @return The partition this region is in.
-     */
-    public String getPartition() {
-        return regionImpl.getPartition();
-    }
-
-    /**
-     * Returns the endpoint for the service given.
-     *
-     * @param endpointPrefix
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    public String getServiceEndpoint(String endpointPrefix) {
-        return regionImpl.getServiceEndpoint(endpointPrefix);
-    }
-
-    /**
-     * Returns whether the given service is supported in this region.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    public boolean isServiceSupported(String serviceName) {
-        return regionImpl.isServiceSupported(serviceName);
-    }
-
-    /**
-     * Returns whether the given service support the https protocol in this region.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    public boolean hasHttpsEndpoint(String serviceName) {
-        return regionImpl.hasHttpsEndpoint(serviceName);
-    }
-
-    /**
-     * Returns whether the given service support the http protocol in this region.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     */
-    public boolean hasHttpEndpoint(String serviceName) {
-        return regionImpl.hasHttpEndpoint(serviceName);
-    }
-
-    /**
-     * Returns a immutable collection of all endpoints available in the
-     * metadata.
-     */
-    public Collection<String> getAvailableEndpoints() {
-        return regionImpl.getAvailableEndpoints();
-    }
-
-    /**
-     * Creates a new service client of the class given and configures it. If
-     * credentials or config are null, defaults will be used.
-     *
-     * @param serviceClass The service client class to instantiate, e.g. AmazonS3Client.class
-     * @param credentials  The credentials provider to use, or null for the default
-     *                     credentials provider
-     * @param config       The configuration to use, or null for the default
-     *                     configuration
-     * @deprecated use appropriate {@link com.amazonaws.client.builder.AwsClientBuilder} implementation
-     *             for the service being constructed. For example:
-     *             {@code AmazonSNSClientBuilder.standard().withRegion(region).build();}
-     */
-    @Deprecated
-    public <T extends AmazonWebServiceClient> T createClient(Class<T> serviceClass,
-                                                             AWSCredentialsProvider credentials,
-                                                             ClientConfiguration config) {
-        Constructor<T> constructor;
-        T client;
-        try {
-            if (credentials == null && config == null) {
-                constructor = serviceClass.getConstructor();
-                client = constructor.newInstance();
-            } else if (credentials == null) {
-                constructor = serviceClass.getConstructor(ClientConfiguration.class);
-                client = constructor.newInstance(config);
-            } else if (config == null) {
-                constructor = serviceClass.getConstructor(AWSCredentialsProvider.class);
-                client = constructor.newInstance(credentials);
-            } else {
-                constructor = serviceClass.getConstructor(AWSCredentialsProvider.class, ClientConfiguration.class);
-                client = constructor.newInstance(credentials, config);
-            }
-
-            client.setRegion(this);
-            return client;
-        } catch (Exception e) {
-            throw new RuntimeException("Couldn't instantiate instance of " + serviceClass, e);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof Region == false)
-            return false;
-
-        Region region = (Region) obj;
-        return this.getName().equals(region.getName());
-    }
-
-    @Override
-    public int hashCode() {
-        return getName().hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return getName();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/RegionMetadataFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadataFactory.java
--- ./src/main/java/com/amazonaws/regions/RegionMetadataFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadataFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,38 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.partitions.PartitionsLoader;
-
-/**
- * A factory to create {@link RegionMetadata}
- */
-public class RegionMetadataFactory {
-
-    private RegionMetadataFactory() {
-    }
-
-    public static RegionMetadata create() {
-        RegionMetadata metadata = createLegacyXmlRegionMetadata();
-        if (metadata == null) {
-            metadata = new RegionMetadata(new PartitionsLoader().build());
-        }
-        return metadata;
-    }
-
-    private static RegionMetadata createLegacyXmlRegionMetadata() {
-        return new LegacyRegionXmlMetadataBuilder().build();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/RegionMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadata.java
--- ./src/main/java/com/amazonaws/regions/RegionMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,99 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import java.util.List;
-
-/**
- * A collection of metadata about a set of regions and the services they
- * contain.
- *
- * @see RegionUtils
- */
-public class RegionMetadata {
-
-    private final RegionMetadataProvider provider;
-
-    /**
-     * Creates a new RegionMetadata object from the given list of regions.
-     *
-     * @param regions the list of regions
-     */
-    public RegionMetadata(final List<Region> regions) {
-        this.provider = new InMemoryRegionsProvider(regions);
-    }
-
-    public RegionMetadata(RegionMetadataProvider provider) {
-        this.provider = provider;
-    }
-
-    /**
-     * Returns an immutable list of all regions known to this region metadata
-     * object, in no particular order.
-     *
-     * @return an immutable list of all regions
-     */
-    public List<Region> getRegions() {
-        return provider.getRegions();
-    }
-
-    /**
-     * Returns the region with the name given, if it exists. Otherwise, returns
-     * null.
-     *
-     * @param name the name of the region to search for
-     * @return the corresponding region, if it exists
-     */
-    public Region getRegion(final String name) {
-        return provider.getRegion(name);
-    }
-
-    /**
-     * Returns a list of the regions that support the service given.
-     *
-     * @param service
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     * @return the list of regions with support for the given service
-     */
-    public List<Region> getRegionsForService(final String service) {
-        return provider.getRegionsForService(service);
-    }
-
-    /**
-     * Searches through all known regions to find one with any service at the
-     * specified endpoint. If no region is found with a service at that
-     * endpoint, an exception is thrown.
-     *
-     * @param endpoint The endpoint for any service residing in the desired region.
-     * @return The region containing any service running at the specified
-     * endpoint, otherwise an exception is thrown if no region is found
-     * with a service at the specified endpoint.
-     * @throws IllegalArgumentException If the given URL is malformed, or if the one of the service
-     *                                  URLs on record is malformed.
-     * @deprecated sdk no longer holds the complete endpoint for every service in the region.
-     * It now uses the partition metadata to compute the endpoints dynamically for new regions and services.
-     */
-    @Deprecated
-    public Region getRegionByEndpoint(final String endpoint) {
-        return provider.getRegionByEndpoint(endpoint);
-    }
-
-    @Override
-    public String toString() {
-        return provider.toString();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/RegionMetadataParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadataParser.java
--- ./src/main/java/com/amazonaws/regions/RegionMetadataParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadataParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,211 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-
-/**
- * Parses a region metadata file to pull out information about the
- * available regions, names, IDs, and what service endpoints are available
- * in each region.
- */
-public class RegionMetadataParser {
-
-    private static final String REGION_TAG = "Region";
-    private static final String REGION_ID_TAG = "Name";
-    private static final String DOMAIN_TAG = "Domain";
-    private static final String ENDPOINT_TAG = "Endpoint";
-    private static final String SERVICE_TAG = "ServiceName";
-    private static final String HTTP_TAG = "Http";
-    private static final String HTTPS_TAG = "Https";
-    private static final String HOSTNAME_TAG = "Hostname";
-
-    /**
-     * Parses the specified input stream and returns a {@code RegionMetadata}
-     * object.
-     *
-     * @param input the input stream to parse
-     * @return the parsed region metadata
-     * @throws IOException on error
-     */
-    public static RegionMetadata parse(final InputStream input)
-            throws IOException {
-
-        return new RegionMetadata(internalParse(input, false));
-    }
-
-    /**
-     * @deprecated since this object is stateless
-     */
-    @Deprecated
-    public RegionMetadataParser() {
-    }
-    
-    /**
-     * Parses the specified input stream and returns a list of the regions
-     * declared in it. By default, verification on the region endpoints is
-     * disabled.
-     * 
-     * @param input
-     *            The stream containing the region metadata to parse.
-     * 
-     * @return The list of parsed regions.
-     * @deprecated in favor of {@link #parse(InputStream)}
-     */
-    @Deprecated
-    public List<Region> parseRegionMetadata(InputStream input)
-            throws IOException {
-
-        return internalParse(input, false);
-    }
-
-    /**
-     * Parses the specified input stream and optionally verifies that all of
-     * the endpoints end in ".amazonaws.com". This method is deprecated, since
-     * not all valid AWS endpoints end in ".amazonaws.com" any more.
-     * 
-     * @param input
-     *            The stream containing the region metadata to parse.
-     * @param endpointVerification
-     *            Whether to verify each region endpoint
-     * 
-     * @return The list of parsed regions.
-     * @deprecated in favor of {@link #parse(InputStream)}
-     */
-    @Deprecated
-    public List<Region> parseRegionMetadata(final InputStream input,
-                                            final boolean endpointVerification)
-            throws IOException {
-
-        return internalParse(input, endpointVerification);
-    }
-
-    private static List<Region> internalParse(
-            final InputStream input,
-            final boolean endpointVerification) throws IOException {
-
-        Document document;
-        try {
-
-            DocumentBuilderFactory factory =
-                DocumentBuilderFactory.newInstance();
-
-            DocumentBuilder documentBuilder = factory.newDocumentBuilder();
-            document = documentBuilder.parse(input);
-
-        } catch (IOException exception) {
-            throw exception;
-        } catch (Exception exception) {
-            throw new IOException("Unable to parse region metadata file: "
-                                  + exception.getMessage(),
-                                  exception);
-        } finally {
-            try {
-                input.close();
-            } catch (IOException exception) {
-            }
-        }
-        
-        NodeList regionNodes = document.getElementsByTagName(REGION_TAG);
-        List<Region> regions = new ArrayList<Region>();
-        for (int i = 0; i < regionNodes.getLength(); i++) {
-            Node node = regionNodes.item(i);
-            if (node.getNodeType() == Node.ELEMENT_NODE) {
-                Element element = (Element)node;
-                regions.add(parseRegionElement(element, endpointVerification));
-            }
-        }
-        
-        return regions;
-    }
-
-    private static Region parseRegionElement(
-            final Element regionElement,
-            final boolean endpointVerification) {
-
-        String name = getChildElementValue(REGION_ID_TAG, regionElement);
-        String domain = getChildElementValue(DOMAIN_TAG, regionElement);
-
-        InMemoryRegionImpl regionImpl = new InMemoryRegionImpl(name, domain);
-
-        NodeList endpointNodes =
-            regionElement.getElementsByTagName(ENDPOINT_TAG);
-
-        for (int i = 0; i < endpointNodes.getLength(); i++) {
-            addRegionEndpoint(regionImpl,
-                              (Element) endpointNodes.item(i),
-                              endpointVerification);
-        }
-
-        return new Region(regionImpl);
-    }
-    
-    private static void addRegionEndpoint(
-            final InMemoryRegionImpl region,
-            final Element endpointElement,
-            final boolean endpointVerification) {
-
-        String serviceName = getChildElementValue(SERVICE_TAG, endpointElement);
-        String hostname = getChildElementValue(HOSTNAME_TAG, endpointElement);
-        String http = getChildElementValue(HTTP_TAG, endpointElement);
-        String https = getChildElementValue(HTTPS_TAG, endpointElement);
-
-        if ( endpointVerification && !verifyLegacyEndpoint(hostname) ) {
-            throw new IllegalStateException("Invalid service endpoint ("
-                                            + hostname + ") is detected.");
-        }
-
-        region.addEndpoint(serviceName, hostname);
-        if (Boolean.valueOf(http)) {
-            region.addHttp(serviceName);
-        }
-        if (Boolean.valueOf(https)) {
-            region.addHttps(serviceName);
-        }
-    }
-
-    private static String getChildElementValue(
-            final String tagName,
-            final Element element) {
-
-        Node tagNode = element.getElementsByTagName(tagName).item(0);
-        if ( tagNode == null )
-            return null;
-        NodeList nodes= tagNode.getChildNodes();
-        Node node = (Node)nodes.item(0); 
-     
-        return node.getNodeValue();    
-    }
-
-    /**
-     * Returns whether the provided endpoint is a "valid" AWS service endpoint
-     * ending in ".amazonaws.com".
-     */
-    private static boolean verifyLegacyEndpoint(String endpoint) {
-        return endpoint.endsWith(".amazonaws.com");
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/RegionMetadataProvider.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadataProvider.java
--- ./src/main/java/com/amazonaws/regions/RegionMetadataProvider.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionMetadataProvider.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,69 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.annotation.SdkInternalApi;
-
-import java.util.List;
-
-@SdkInternalApi
-public interface RegionMetadataProvider {
-
-    /**
-     * Returns an immutable list of all regions known to this region metadata
-     * object, in no particular order.
-     *
-     * @return an immutable list of all regions
-     */
-    List<Region> getRegions();
-
-    /**
-     * Returns the region with the name given, if it exists in the metadata
-     * or if it can be derived from the metadata.
-     * Otherwise, returns null.
-     *
-     * @param regionName the name of the region to search for
-     * @return the corresponding region, if it exists or derived.
-     */
-    Region getRegion(final String regionName);
-
-    /**
-     * Returns a list of the regions that support the service given.
-     *
-     * @param serviceName
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface,
-     *         e.g. AmazonEC2.ENDPOINT_PREFIX.
-     * @return the list of regions with support for the given service
-     */
-    List<Region> getRegionsForService(final String serviceName);
-
-    /**
-     * Searches through all known regions to find one with any service at the
-     * specified endpoint. If no region is found with a service at that
-     * endpoint, an exception is thrown.
-     *
-     * @param endpoint The endpoint for any service residing in the desired region.
-     * @return The region containing any service running at the specified
-     * endpoint, otherwise an exception is thrown if no region is found
-     * with a service at the specified endpoint.
-     * @throws IllegalArgumentException If the given URL is malformed, or if the one of the service
-     *                                  URLs on record is malformed.
-     * @deprecated sdk no longer holds the complete endpoint for every service in the region.
-     * It now uses the partition metadata to compute the endpoints dynamically for new regions and services.
-     */
-    @Deprecated
-    Region getRegionByEndpoint(final String endpoint);
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/Regions.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/Regions.java
--- ./src/main/java/com/amazonaws/regions/Regions.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/Regions.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.AmazonClientException;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.util.EC2MetadataUtils;
-
-/**
- * Enumeration of region names
- */
-public enum Regions {
-
-    GovCloud("us-gov-west-1"),
-    US_EAST_1("us-east-1"),
-    US_EAST_2("us-east-2"),
-    US_WEST_1("us-west-1"),
-    US_WEST_2("us-west-2"),
-    EU_WEST_1("eu-west-1"),
-    EU_WEST_2("eu-west-2"),
-    EU_WEST_3("eu-west-3"),
-    EU_CENTRAL_1("eu-central-1"),
-    AP_SOUTH_1("ap-south-1"),
-    AP_SOUTHEAST_1("ap-southeast-1"),
-    AP_SOUTHEAST_2("ap-southeast-2"),
-    AP_NORTHEAST_1("ap-northeast-1"),
-    AP_NORTHEAST_2("ap-northeast-2"),
-    SA_EAST_1("sa-east-1"),
-    CN_NORTH_1("cn-north-1"),
-    CN_NORTHWEST_1("cn-northwest-1"),
-    CA_CENTRAL_1("ca-central-1");
-
-    /**
-     * The default region that new customers in the US are encouraged to use
-     * when using AWS services for the first time.
-     */
-    public static final Regions DEFAULT_REGION = US_WEST_2;
-
-    private final String name;
-
-    private Regions(String name) {
-        this.name = name;
-    }
-
-    /**
-     * The name of this region, used in the regions.xml file to identify it.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns a region enum corresponding to the given region name.
-     *
-     * @param regionName
-     *            The name of the region. Ex.: eu-west-1
-     * @return Region enum representing the given region name.
-     */
-    public static Regions fromName(String regionName) {
-        for (Regions region : Regions.values()) {
-            if (region.getName().equals(regionName)) {
-                return region;
-            }
-        }
-        throw new IllegalArgumentException("Cannot create enum from " + regionName + " value!");
-    }
-
-    /**
-     * Returns a Region object representing the region the application is
-     * running in, when running in EC2. If this method is called from a non-EC2
-     * environment, it will return null.
-     */
-    public static Region getCurrentRegion() {
-        try {
-            final String region = EC2MetadataUtils.getEC2InstanceRegion();
-            if (region != null)
-                return RegionUtils.getRegion(region);
-        } catch (AmazonClientException e) {
-            LogFactory.getLog(Regions.class).debug(
-                "Ignoring failure to retrieve the region: " + e.getMessage());
-        }
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/regions/RegionUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionUtils.java
--- ./src/main/java/com/amazonaws/regions/RegionUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/RegionUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,350 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.regions;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.ClientConfiguration;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.List;
-
-/**
- * Utilities for working with regions.
- */
-public class RegionUtils {
-
-    private static volatile RegionMetadata regionMetadata;
-
-    /*
-     * Convenience methods that access the singleton RegionMetadata instance
-     * maintained by this class, lazily initializing it if need be.
-     */
-
-    /**
-     * Returns the current set of region metadata for this process,
-     * initializing it if it has not yet been explicitly initialized before.
-     *
-     * @return the current set of region metadata
-     */
-    public static RegionMetadata getRegionMetadata() {
-        RegionMetadata rval = regionMetadata;
-        if (rval != null) {
-            return rval;
-        }
-
-        synchronized (RegionUtils.class) {
-            if (regionMetadata == null) {
-                initialize();
-            }
-        }
-
-        return regionMetadata;
-    }
-
-    /**
-     * Initializes the region metadata by loading from the default hierarchy
-     * of region metadata locations.
-     */
-    public static void initialize() {
-        regionMetadata = RegionMetadataFactory.create();
-    }
-
-    /**
-     * Directly sets the singleton {@code RegionMetadata} instance.
-     *
-     * @param metadata the new region metadata object
-     */
-    public static void initializeWithMetadata(final RegionMetadata metadata) {
-        if (metadata == null) {
-            throw new IllegalArgumentException("metadata cannot be null");
-        }
-        regionMetadata = metadata;
-    }
-
-    /**
-     * Returns a list of the available AWS regions.
-     */
-    public static List<Region> getRegions() {
-        return getRegionMetadata().getRegions();
-    }
-
-    /**
-     * Returns a list of the regions that support the service given.
-     *
-     * @param serviceAbbreviation
-     *         The service endpoint prefix which can be retrieved from the
-     *         constant ENDPOINT_PREFIX of the specific service client interface.
-     *
-     */
-    public static List<Region> getRegionsForService(
-            String serviceAbbreviation) {
-
-        return getRegionMetadata().getRegionsForService(serviceAbbreviation);
-    }
-
-    /**
-     * Returns the region with the id given, if it exists. Otherwise, returns
-     * null.
-     */
-    public static Region getRegion(String regionName) {
-        return getRegionMetadata().getRegion(regionName);
-    }
-
-    /*
-     * Methods for loading a RegionMetadata object from various locations.
-     */
-
-    /**
-     * Loads a set of region metadata by downloading an XML file from the
-     * given URI and parsing it.
-     *
-     * @param uri the uri of the XML file to parse
-     * @return the parsed region metadata
-     * @throws IOException on error fetching or parsing the XML file
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromURI(final URI uri)
-            throws IOException {
-        return loadMetadataFromURI(uri, null);
-    }
-
-    /**
-     * Loads a set of region metadata by downloading an XML file from the
-     * given URI and parsing it.
-     *
-     * @param uri    the uri of the XML file to parse
-     * @param config configuration for the HTTP client to use to fetch the file
-     * @return the parsed region metadata
-     * @throws IOException on error fetching or parsing the XML file
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromURI(
-            final URI uri,
-            final ClientConfiguration config) throws IOException {
-        return LegacyRegionXmlLoadUtils.load(uri, config);
-    }
-
-    /**
-     * Loads a set of region metadata from an XML file on disk.
-     *
-     * @param file the file to load from
-     * @return the loaded region metadata
-     * @throws IOException on error opening or reading from the file
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromFile(final File file)
-            throws IOException {
-        return LegacyRegionXmlLoadUtils.load(file);
-    }
-
-    /**
-     * Loads a set of region metadata from an XML file stored as a resource
-     * of the classloader used to load the RegionUtils class.
-     *
-     * @param name the path of the resource, relative to the RegionUtils class
-     * @return the parsed region metadata
-     * @throws IOException if the resource is not found or cannot be parsed
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromResource(final String name)
-            throws IOException {
-
-        return LegacyRegionXmlLoadUtils.load(RegionUtils
-                .class, name);
-    }
-
-    /**
-     * Loads a set of region metadata from an XML file stored as a resource of
-     * the classloader used to load the given class.
-     *
-     * @param clazz the class to use as a base for the resource
-     * @param name  the path to the resource, relative to the given class
-     * @return the parsed region metadata
-     * @throws IOException if the resource is not found or cannot be parsed
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromResource(
-            final Class<?> clazz,
-            final String name) throws IOException {
-
-        return LegacyRegionXmlLoadUtils.load(clazz, name);
-    }
-
-    /**
-     * Loads a set of region metadata from an XML file stored as a resource
-     * of the given classloader.
-     *
-     * @param classLoader the class loader to load the resource from
-     * @param name        the path to the resource
-     * @return the parsed region metadata
-     * @throws IOException if the resource is not found or cannot be parsed
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromResource(
-            final ClassLoader classLoader,
-            final String name) throws IOException {
-
-        return LegacyRegionXmlLoadUtils.load(classLoader,
-                name);
-    }
-
-    /**
-     * Loads a set of region metadata from an arbitrary {@code InputStream}
-     * containing an XML file.
-     *
-     * @param stream the stream to load from
-     * @return the loaded region metadata
-     * @throws IOException on error reading from the stream
-     */
-    @Deprecated
-    public static RegionMetadata loadMetadataFromInputStream(
-            final InputStream stream) throws IOException {
-
-        return LegacyRegionXmlLoadUtils.load(stream);
-    }
-
-    /*
-     * Methods for initializing the process-wide singleton RegionMetadata
-     * instance.
-     */
-
-    /**
-     * This method no longer attempts to retrieve region metadata from
-     * CloudFront, as that file is no longer being maintained and the version
-     * bundled with the SDK is likely to be more up-to-date.
-     * <p/>
-     * It's deprecated to signal that it no longer has any possibility of
-     * retrieving a newer set of metadata than was previously loaded. If you
-     * are simply wanting to reinitialize from the bundled region metadata,
-     * call {@code initialize}. If you want to maintain your own remote
-     * copy of the region metadata and periodically refresh it at runtime,
-     * call {@code initializeFromURI}.
-     *
-     * @deprecated in favor of {@link #initialize()}
-     */
-    @Deprecated
-    public static void init() {
-        initialize();
-    }
-
-    /**
-     * Loads a set of region metadata by downloading an XML file from the
-     * given URI and parsing it.
-     *
-     * @param uri the uri of the XML file to parse
-     * @throws SdkClientException on error
-     */
-    @Deprecated
-    public static synchronized void initializeFromURI(final URI uri) {
-        initializeFromURI(uri, null);
-    }
-
-    /**
-     * Loads a set of region metadata by downloading an XML file from the
-     * given URI and parsing it.
-     *
-     * @param uri    the uri of the XML file to parse
-     * @param config configuration for the HTTP client to use to fetch the file
-     * @throws SdkClientException on error
-     */
-    @Deprecated
-    public static synchronized void initializeFromURI(
-            final URI uri,
-            final ClientConfiguration config) {
-        try {
-
-            regionMetadata = loadMetadataFromURI(uri, config);
-
-        } catch (IOException exception) {
-            throw new SdkClientException(
-                    "Error parsing region metadata from " + uri,
-                    exception);
-        }
-    }
-
-    /**
-     * Initializes the region metadata singleton from an XML file on disk.
-     *
-     * @param file the file to load from
-     * @throws SdkClientException on error opening or reading from the file
-     */
-    @Deprecated
-    public static synchronized void initializeFromFile(final File file) {
-        try {
-            regionMetadata = loadMetadataFromFile(file);
-        } catch (IOException exception) {
-            throw new SdkClientException(
-                    "Error parsing region metadata from " + file,
-                    exception);
-        }
-    }
-
-    /**
-     * Initializes the region metadata singleton from an XML file stored as a
-     * resource of the classloader used to load the RegionUtils class.
-     *
-     * @param name the path of the resource, relative to the RegionUtils class
-     * @throws SdkClientException on error
-     */
-    @Deprecated
-    public static synchronized void initializeFromResource(final String name) {
-        initializeFromResource(RegionUtils.class, name);
-    }
-
-    /**
-     * Initializes the region metadata singleton from the given resource.
-     *
-     * @param clazz the class to use as a base for the resource
-     * @param name  the path to the resource, relative to the given class
-     * @throws SdkClientException on error
-     */
-    @Deprecated
-    public static synchronized void initializeFromResource(
-            final Class<?> clazz,
-            final String name) {
-
-        try {
-            regionMetadata = loadMetadataFromResource(clazz, name);
-        } catch (IOException exception) {
-            throw new SdkClientException(
-                    "Error parsing region metadata from resource " + name,
-                    exception);
-        }
-    }
-
-    /**
-     * Initializes the region metadata singleton from the given resource.
-     *
-     * @param classLoader the class loader to use to load the resource
-     * @param name        the path to the resource
-     * @throws SdkClientException on error
-     */
-    @Deprecated
-    public static synchronized void initializeFromResource(
-            final ClassLoader classLoader,
-            final String name) {
-
-        try {
-            regionMetadata = loadMetadataFromResource(classLoader, name);
-        } catch (IOException exception) {
-            throw new SdkClientException(
-                    "Error parsing region metadata from resource " + name,
-                    exception);
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/regions/ServiceAbbreviations.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/ServiceAbbreviations.java
--- ./src/main/java/com/amazonaws/regions/ServiceAbbreviations.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/regions/ServiceAbbreviations.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,86 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.regions;
-
-
-/**
- * Abbreviations for looking up information about a specific service. Used in
- * {@link Region#getServiceEndpoint(String)} and related methods.
- *
- * @deprecated use the constant ENDPOINT_PREFIX from the specific service client
- *             interface instead for retrieving the specific service abbreviation,
- *             e.g. AmazonEC2.ENDPOINT_PREFIX.
- */
-
-@Deprecated
-public final class ServiceAbbreviations {
-    public static final String Autoscaling = "autoscaling";
-    public static final String CloudFormation = "cloudformation";
-    public static final String CloudFront = "cloudfront";
-    public static final String CloudHSM = "cloudhsm";
-    public static final String CloudSearch = "cloudsearch";
-    public static final String CloudTrail = "cloudtrail";
-    public static final String CloudWatch = "monitoring";
-    public static final String CloudWatchLogs = "logs";
-    public static final String CodeDeploy = "codedeploy";
-    public static final String CodeCommit = "codecommit";
-    public static final String CodePipeline = "codepipeline";
-    public static final String CognitoIdentity = "cognito-identity";
-    public static final String CognitoIdentityProvider = "cognito-idp";
-    public static final String CognitoSync = "cognito-sync";
-    public static final String Config = "config";
-    public static final String DeviceFarm = "devicefarm";
-    public static final String DataPipeline = "datapipeline";
-    public static final String DirectConnect = "directconnect";
-    public static final String Directory = "ds";
-    public static final String DMS = "dms";
-    public static final String Dynamodb = "dynamodb";
-    public static final String DynamodbStreams = "streams.dynamodb";
-    public static final String EC2 = "ec2";
-    public static final String EC2ContainerService = "ecs";
-    public static final String EC2SimpleSystemsManager = "ssm";
-    public static final String Elasticache = "elasticache";
-    public static final String ElasticBeanstalk = "elasticbeanstalk";
-    public static final String ElasticFileSystem = "elasticfilesystem";
-    public static final String ElasticLoadbalancing = "elasticloadbalancing";
-    public static final String ElasticMapReduce = "elasticmapreduce";
-    public static final String ElasticTranscoder = "elastictranscoder";
-    public static final String Email = "email";
-    public static final String GameLift = "gamelift";
-    public static final String Glacier = "glacier";
-    public static final String IAM = "iam";
-    public static final String IoT = "iot";
-    public static final String IoTData = "data.iot";
-    public static final String ImportExport = "importexport";
-    public static final String KeyManagementService = "kms";
-    public static final String Kinesis = "kinesis";
-    public static final String Lambda = "lambda";
-    public static final String MachineLearning = "machinelearning";
-    public static final String Opsworks = "opsworks";
-    public static final String RDS = "rds";
-    public static final String RedShift = "redshift";
-    public static final String Route53 = "route53";
-    public static final String Route53Domains = "route53domains";
-    public static final String S3 = "s3";
-    public static final String SimpleDB = "sdb";
-    public static final String SimpleWorkflow = "swf";
-    public static final String SNS = "sns";
-    public static final String SQS = "sqs";
-    public static final String StorageGateway = "storagegateway";
-    public static final String STS = "sts";
-    public static final String Support = "support";
-    public static final String WAF = "waf";
-    public static final String Workspaces = "workspaces";
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/RequestClientOptions.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/RequestClientOptions.java
--- ./src/main/java/com/amazonaws/RequestClientOptions.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/RequestClientOptions.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,120 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.NotThreadSafe;
-
-import java.io.InputStream;
-import java.util.EnumMap;
-
-/**
- * Client request options such as client markers for individual
- * {@link AmazonWebServiceRequest}s.
- */
-@NotThreadSafe
-public final class RequestClientOptions {
-    /**
-     * Used to enable mark-and-reset for
-     * non-mark-and-resettable non-file input stream for up to 128K memory
-     * buffering by default. Add 1 to get around an implementation quirk of
-     * BufferedInputStream.
-     *
-     * Retries after reading {@link #DEFAULT_STREAM_BUFFER_SIZE} bytes would
-     * fail to reset the underlying input stream as the mark position would
-     * have been invalidated.
-     *
-     */
-    public static final int DEFAULT_STREAM_BUFFER_SIZE = (1 << 17)+1;
-    public static enum Marker {
-        /**
-         * Used to specify the http user_agent value.
-         * This marker is intended only for internal use by the AWS SDK.
-         */
-        USER_AGENT,
-        ;
-    }
-
-    private final EnumMap<Marker,String> markers = new EnumMap<Marker,String>(Marker.class);
-    /**
-     * Used for mark-and-reset purposes during retry.
-     */
-    private int readLimit = DEFAULT_STREAM_BUFFER_SIZE;
-
-    /**
-     * Returns the value of the specified marker; or null if there is no such
-     * value.
-     */
-    public String getClientMarker(Marker marker) {
-        return markers.get(marker);
-    }
-
-    /**
-     * Associates the given value with the given marker.
-     * Note the {@link Marker#USER_AGENT} is only intended for internal use
-     * by the AWS SDK.
-     */
-    public void putClientMarker(Marker marker, String value) {
-        markers.put(marker, value);
-    }
-
-    /**
-     * Appends a user agent to the USER_AGENT client marker.
-     * This method is intended only for internal use by the AWS SDK.
-     */
-    public void appendUserAgent(String userAgent) {
-        String marker = markers.get(Marker.USER_AGENT);
-        if (marker == null)
-            marker = "";
-        marker = createUserAgentMarkerString(marker, userAgent);
-        putClientMarker(Marker.USER_AGENT, marker);
-    }
-
-    /**
-     * Appends the given client marker string to the existing one and returns it.
-     */
-    private String createUserAgentMarkerString(final String marker, String userAgent) {
-        return marker.contains(userAgent) ? marker : marker + " " + userAgent;
-    }
-
-    /**
-     * Returns the mark-and-reset read limit; defaults to
-     * {@value #DEFAULT_STREAM_BUFFER_SIZE}.
-     *
-     * @see InputStream#mark(int)
-     */
-    public final int getReadLimit() {
-        return readLimit;
-    }
-
-    /**
-     * Sets the optional mark-and-reset read limit used for signing and retry
-     * purposes.
-     *
-     * @see InputStream#mark(int)
-     */
-    public final void setReadLimit(int readLimit) {
-        this.readLimit = readLimit;
-    }
-
-    /**
-     * Copy the internal states of this <code>RequestClientOptions</code> to the
-     * target <code>RequestClientOptions</code>.
-     */
-    void copyTo(RequestClientOptions target) {
-        target.setReadLimit(getReadLimit());
-        for (Marker marker: Marker.values())
-            target.putClientMarker(marker, getClientMarker(marker));
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/RequestConfig.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/RequestConfig.java
--- ./src/main/java/com/amazonaws/RequestConfig.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/RequestConfig.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,74 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.event.ProgressListener;
-import com.amazonaws.internal.AmazonWebServiceRequestAdapter;
-import com.amazonaws.metrics.RequestMetricCollector;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Generic representation of request level configuration. The customer interface for specifying
- * request level configuration is a base request class with configuration methods.
- */
-@SdkProtectedApi
-public abstract class RequestConfig {
-
-    /**
-     * No op implementation to initalize request config in {@link DefaultRequest}.
-     */
-    public static final RequestConfig NO_OP = new AmazonWebServiceRequestAdapter(
-            AmazonWebServiceRequest.NOOP);
-
-    public abstract ProgressListener getProgressListener();
-
-    public abstract RequestMetricCollector getRequestMetricsCollector();
-
-    public abstract AWSCredentialsProvider getCredentialsProvider();
-
-    /**
-     * @return A non null map of custom headers to inject into the request.
-     */
-    public abstract Map<String, String> getCustomRequestHeaders();
-
-    /**
-     * @return A non null map of custom query parameters to inject into the request.
-     */
-    public abstract Map<String, List<String>> getCustomQueryParameters();
-
-    public abstract Integer getRequestTimeout();
-
-    public abstract Integer getClientExecutionTimeout();
-
-    public abstract RequestClientOptions getRequestClientOptions();
-
-    /**
-     * @return String identifying the 'type' (i.e. operation) of the request. Used in metrics
-     * subsystem.
-     */
-    public abstract String getRequestType();
-
-    /**
-     * @return The original request object. May be delivered to various strategies or hooks for
-     * extra context. I.E. {@link com.amazonaws.handlers.RequestHandler2} or {@link
-     * com.amazonaws.retry.RetryPolicy}.
-     */
-    public abstract Object getOriginalRequest();
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/Request.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/Request.java
--- ./src/main/java/com/amazonaws/Request.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/Request.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,150 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws;
-
-import com.amazonaws.http.HttpMethodName;
-import com.amazonaws.util.AWSRequestMetrics;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Represents a request being sent to an Amazon Web Service, including the
- * parameters being sent as part of the request, the endpoint to which the
- * request should be sent, etc.
- * <p>
- * This class is only intended for use inside the AWS client libraries and
- * request handlers. Users of the AWS SDK for Java should not implement this
- * interface.
- *
- * @param <T>
- *            The type of original, user facing request represented by this
- *            request.
- */
-public interface Request<T> extends SignableRequest<T>, HandlerContextAware {
-    /**
-     * Sets all headers, clearing any existing ones.
-     */
-    void setHeaders(Map<String, String> headers);
-
-    /**
-     * Sets the path to the resource being requested.
-     *
-     * @param path
-     *            The path to the resource being requested.
-     */
-    void setResourcePath(String path);
-
-    /**
-     * Adds the specified request parameter to this request, and returns the
-     * updated request object.
-     *
-     * @param name
-     *            The name of the request parameter.
-     * @param value
-     *            The value of the request parameter.
-     *
-     * @return The updated request object.
-     */
-    Request<T> withParameter(String name, String value);
-
-    /**
-     * Sets all parameters, clearing any existing values.
-     *
-     * Note that List values within the parameters Map must use an implementation that supports null
-     * values.
-     */
-    void setParameters(Map<String, List<String>> parameters);
-
-    /**
-     * Adds the specified request parameter and list of values to this request.
-     *
-     * @param name
-     *            The name of the request parameter.
-     * @param values
-     *            The value of the request parameter.
-     */
-    void addParameters(String name, List<String> values);
-
-    /**
-     * Sets the service endpoint (ex: "https://ec2.amazonaws.com") to which this
-     * request should be sent.
-     *
-     * @param endpoint
-     *            The service endpoint to which this request should be sent.
-     */
-    void setEndpoint(URI endpoint);
-
-    /**
-     * Sets the HTTP method (GET, POST, etc) to use when sending this request.
-     *
-     * @param httpMethod
-     *            The HTTP method to use when sending this request.
-     */
-    void setHttpMethod(HttpMethodName httpMethod);
-
-    /**
-     * @return The name of the Amazon service this request is for. This is used
-     *         as the service name set in request metrics and service
-     *         exceptions. This is NOT the same as the service name returned by
-     *         {@link AmazonWebServiceClient#getServiceName()} which is used for
-     *         signing purpose.
-     *
-     * @see {@link AmazonServiceException#getServiceName()}
-     * @see {@link AWSRequestMetrics.Field#ServiceName}
-     */
-    String getServiceName();
-
-    /**
-     * Returns the original, user facing request object which this internal
-     * request object is representing.
-     */
-    AmazonWebServiceRequest getOriginalRequest();
-
-    /**
-     * Sets the optional value for time offset for this request.  This
-     * will be used by the signer to adjust for potential clock skew.
-     * Value is in seconds, positive values imply the current clock is "fast",
-     * negative values imply clock is slow.
-     *
-     * @param timeOffset
-     *            The optional value for time offset (in seconds) for this request.
-     */
-    void setTimeOffset(int timeOffset);
-
-    /**
-     * Sets the optional value for time offset for this request.  This
-     * will be used by the signer to adjust for potential clock skew.
-     * Value is in seconds, positive values imply the current clock is "fast",
-     * negative values imply clock is slow.
-     *
-     * @return The updated request object.
-     */
-    Request<T> withTimeOffset(int timeOffset);
-
-    /**
-     * Returns the request metrics.
-     */
-    AWSRequestMetrics getAWSRequestMetrics();
-
-    /**
-     * Bind the request metrics to the request. Note metrics can be captured
-     * before the request is created.
-     *
-     * @throws IllegalStateException if the binding has already occurred
-     */
-    void setAWSRequestMetrics(AWSRequestMetrics metrics);
-}
diff -Nau8r ./src/main/java/com/amazonaws/ResetException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ResetException.java
--- ./src/main/java/com/amazonaws/ResetException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ResetException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,62 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-/**
- * Stream reset failure.
- */
-public class ResetException extends SdkClientException {
-    private static final long serialVersionUID = 1L;
-    private String extraInfo;
-
-    public ResetException(String message, Throwable t) {
-        super(message, t);
-    }
-
-    public ResetException(Throwable t) {
-        super("", t);
-    }
-
-    public ResetException(String message) {
-        super(message);
-    }
-
-    public ResetException() {
-        super("");
-    }
-
-    /**
-     * {@inheritDoc}
-     * A stream reset exception cannot be retried.
-     */
-    @Override
-    public boolean isRetryable() {
-        return false;
-    }
-
-    @Override
-    public String getMessage() {
-        String msg = super.getMessage();
-        return extraInfo == null ? msg : msg + ";  " + extraInfo;
-    }
-
-    public String getExtraInfo() {
-        return extraInfo;
-    }
-
-    public void setExtraInfo(String extraInfo) {
-        this.extraInfo = extraInfo;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/Response.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/Response.java
--- ./src/main/java/com/amazonaws/Response.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/Response.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,34 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.http.HttpResponse;
-
-/**
- * Response wrapper to provide access to not only the original AWS response
- * but also the associated http response.
- *
- * @param <T> the underlying AWS response type.
- */
-public final class Response<T> {
-    private final T response;
-    private final HttpResponse httpResponse;
-    public Response(T response, HttpResponse httpResponse) {
-        this.response = response;
-        this.httpResponse = httpResponse;
-    }
-    public T getAwsResponse() { return response; }
-    public HttpResponse getHttpResponse() { return httpResponse; }
-}
diff -Nau8r ./src/main/java/com/amazonaws/ResponseMetadata.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ResponseMetadata.java
--- ./src/main/java/com/amazonaws/ResponseMetadata.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ResponseMetadata.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,73 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import java.util.Map;
-
-/**
- * Represents additional metadata included with a response from AWS. Response
- * metadata varies by service, but all services return an AWS request ID that
- * can be used in the event a service call isn't working as expected and you
- * need to work with AWS support to debug an issue.
- * <p>
- * Access to AWS request IDs is also available through the com.amazonaws.request
- * logger in the AWS SDK for Java.
- */
-public class ResponseMetadata {
-    public static final String AWS_REQUEST_ID = "AWS_REQUEST_ID";
-
-    protected final Map<String, String> metadata;
-
-    /**
-     * Creates a new ResponseMetadata object from a specified map of raw
-     * metadata information.
-     * 
-     * @param metadata
-     *            The raw metadata for the new ResponseMetadata object.
-     */
-    public ResponseMetadata(Map<String, String> metadata) {
-        this.metadata = metadata;
-    }
-
-    /**
-     * Creates a new ResponseMetadata object from an existing ResponseMetadata
-     * object.
-     *
-     * @param originalResponseMetadata
-     *            The ResponseMetadata object from which to create the new
-     *            object.
-     */
-    public ResponseMetadata(ResponseMetadata originalResponseMetadata) {
-        this(originalResponseMetadata.metadata);
-    }
-
-    /**
-     * Returns the AWS request ID contained in this response metadata object.
-     * AWS request IDs can be used in the event a service call isn't working as
-     * expected and you need to work with AWS support to debug an issue.
-     *
-     * @return The AWS request ID contained in this response metadata object.
-     */
-    public String getRequestId() {
-        return metadata.get(AWS_REQUEST_ID);
-    }
-
-    @Override
-    public String toString() {
-        if (metadata == null) return "{}";
-        return metadata.toString();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/internal/AuthErrorRetryStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/AuthErrorRetryStrategy.java
--- ./src/main/java/com/amazonaws/retry/internal/AuthErrorRetryStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/AuthErrorRetryStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,34 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.internal;
-
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.Request;
-import com.amazonaws.http.HttpResponse;
-
-/**
- * For internal use only.
- */
-public interface AuthErrorRetryStrategy {
-
-	/**
-	 * Returns an alternative signing context (consists of a new signer instance
-	 * and a new request endpoint) that should be used to retry the request. Or
-	 * null if it should not be retried.
-	 */
-	AuthRetryParameters shouldRetryWithAuthParam(Request<?> originalRequest,
-			HttpResponse response, AmazonServiceException ase);
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/internal/AuthRetryParameters.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/AuthRetryParameters.java
--- ./src/main/java/com/amazonaws/retry/internal/AuthRetryParameters.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/internal/AuthRetryParameters.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,51 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.internal;
-
-import java.net.URI;
-
-import com.amazonaws.annotation.Immutable;
-import com.amazonaws.auth.Signer;
-
-/**
- * Signer and endpoint parameters that are to be used for the next retry.
- * <p>
- * For internal use only.
- */
-@Immutable
-public class AuthRetryParameters {
-
-    private final Signer signerForRetry;
-    private final URI endpointForRetry;
-
-    public AuthRetryParameters(Signer signer, URI endpoint) {
-        if (signer == null)
-            throw new NullPointerException("signer");
-        if (endpoint == null)
-            throw new NullPointerException("endpoint");
-
-        this.signerForRetry = signer;
-        this.endpointForRetry = endpoint;
-    }
-
-    public Signer getSignerForRetry() {
-        return signerForRetry;
-    }
-
-    public URI getEndpointForRetry() {
-        return endpointForRetry;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/PredefinedBackoffStrategies.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/PredefinedBackoffStrategies.java
--- ./src/main/java/com/amazonaws/retry/PredefinedBackoffStrategies.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/PredefinedBackoffStrategies.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,158 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.retry.v2.BackoffStrategy;
-import com.amazonaws.retry.v2.RetryPolicyContext;
-import com.amazonaws.util.ValidationUtils;
-
-import java.util.Random;
-
-/**
- * This class includes a set of pre-defined backoff policies.
- * See this blog for more information on the different algorithms:
- * https://www.awsarchitectureblog.com/2015/03/backoff.html
- */
-public class PredefinedBackoffStrategies {
-
-    /**
-     * Default base sleep time (milliseconds) for non-throttled exceptions.
-     **/
-    private static final int SDK_DEFAULT_BASE_DELAY = 100;
-
-    /**
-     * Default base sleep time (milliseconds) for throttled exceptions.
-     **/
-    static final int SDK_DEFAULT_THROTTLED_BASE_DELAY = 500;
-
-    /**
-     * Default maximum back-off time before retrying a request
-     */
-    static final int SDK_DEFAULT_MAX_BACKOFF_IN_MILLISECONDS = 20 * 1000;
-
-    /**
-     * Default base sleep time for DynamoDB.
-     **/
-    static final int DYNAMODB_DEFAULT_BASE_DELAY = 25;
-
-    /**
-     * Maximum retry limit. Avoids integer overflow issues.
-     *
-     * NOTE: If the value is greater than 30, there can be integer overflow
-     * issues during delay calculation.
-     **/
-    private static final int MAX_RETRIES = 30;
-
-    public static class FullJitterBackoffStrategy extends V2CompatibleBackoffStrategyAdapter {
-
-        private final int baseDelay;
-        private final int maxBackoffTime;
-        private final Random random = new Random();
-
-        public FullJitterBackoffStrategy(final int baseDelay,
-                                         final int maxBackoffTime) {
-            this.baseDelay = ValidationUtils.assertIsPositive(baseDelay, "Base delay");
-            this.maxBackoffTime = ValidationUtils.assertIsPositive(maxBackoffTime, "Max backoff");
-        }
-
-
-        @Override
-        public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-            int ceil = calculateExponentialDelay(context.retriesAttempted(), baseDelay, maxBackoffTime);
-            return random.nextInt(ceil);
-        }
-    }
-
-    public static class EqualJitterBackoffStrategy extends V2CompatibleBackoffStrategyAdapter {
-
-        private final int baseDelay;
-        private final int maxBackoffTime;
-        private final Random random = new Random();
-
-        public EqualJitterBackoffStrategy(final int baseDelay,
-                                          final int maxBackoffTime) {
-            this.baseDelay = ValidationUtils.assertIsPositive(baseDelay, "Base delay");
-            this.maxBackoffTime = ValidationUtils.assertIsPositive(maxBackoffTime, "Max backoff");
-        }
-
-        @Override
-        public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-            int ceil = calculateExponentialDelay(context.retriesAttempted(), baseDelay, maxBackoffTime);
-            return (ceil / 2) + random.nextInt((ceil / 2) + 1);
-        }
-    }
-
-    public static class ExponentialBackoffStrategy extends V2CompatibleBackoffStrategyAdapter {
-
-        private final int baseDelay;
-        private final int maxBackoffTime;
-
-        public ExponentialBackoffStrategy(final int baseDelay,
-                                          final int maxBackoffTime) {
-            this.baseDelay = ValidationUtils.assertIsPositive(baseDelay, "Base delay");
-            this.maxBackoffTime = ValidationUtils.assertIsPositive(maxBackoffTime, "Max backoff");
-        }
-
-        @Override
-        public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-            return calculateExponentialDelay(context.retriesAttempted(), baseDelay, maxBackoffTime);
-        }
-    }
-
-    private static int calculateExponentialDelay(int retriesAttempted, int baseDelay, int maxBackoffTime) {
-        int retries = Math.min(retriesAttempted, MAX_RETRIES);
-        return (int) Math.min((1L << retries) * baseDelay, maxBackoffTime);
-    }
-
-
-    /**
-     * A private class that implements the default back-off strategy.
-     **/
-    public static class SDKDefaultBackoffStrategy extends V2CompatibleBackoffStrategyAdapter {
-
-        private final BackoffStrategy fullJitterBackoffStrategy;
-        private final BackoffStrategy equalJitterBackoffStrategy;
-
-        public SDKDefaultBackoffStrategy() {
-            fullJitterBackoffStrategy = new PredefinedBackoffStrategies.FullJitterBackoffStrategy(
-                    SDK_DEFAULT_BASE_DELAY, SDK_DEFAULT_MAX_BACKOFF_IN_MILLISECONDS);
-            equalJitterBackoffStrategy = new PredefinedBackoffStrategies.EqualJitterBackoffStrategy(
-                    SDK_DEFAULT_THROTTLED_BASE_DELAY, SDK_DEFAULT_MAX_BACKOFF_IN_MILLISECONDS);
-        }
-
-        public SDKDefaultBackoffStrategy(final int baseDelay, final int throttledBaseDelay, final int maxBackoff) {
-            fullJitterBackoffStrategy = new PredefinedBackoffStrategies.FullJitterBackoffStrategy(
-                    baseDelay, maxBackoff);
-            equalJitterBackoffStrategy = new PredefinedBackoffStrategies.EqualJitterBackoffStrategy(
-                    throttledBaseDelay, maxBackoff);
-        }
-
-        @Override
-        public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-            /*
-             * We use the full jitter scheme for non-throttled exceptions and the
-             * equal jitter scheme for throttled exceptions.  This gives a preference
-             * to quicker response and larger retry distribution for service errors
-             * and guarantees a minimum delay for throttled exceptions.
-             */
-            if (RetryUtils.isThrottlingException(context.exception())) {
-                return equalJitterBackoffStrategy.computeDelayBeforeNextRetry(context);
-            } else {
-                return fullJitterBackoffStrategy.computeDelayBeforeNextRetry(context);
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/retry/PredefinedRetryPolicies.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/PredefinedRetryPolicies.java
--- ./src/main/java/com/amazonaws/retry/PredefinedRetryPolicies.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/PredefinedRetryPolicies.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,199 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.ClientConfiguration;
-import java.io.IOException;
-
-/**
- * This class includes a set of pre-defined retry policies, including default
- * policies used by SDK.
- */
-public class PredefinedRetryPolicies {
-
-    /** No retry policy **/
-    public static final RetryPolicy NO_RETRY_POLICY = new RetryPolicy(
-            RetryPolicy.RetryCondition.NO_RETRY_CONDITION,
-            RetryPolicy.BackoffStrategy.NO_DELAY,
-            0,      // maxErrorRetry
-            false); // honorMaxErrorRetryInClientConfig
-
-    /* SDK default */
-
-    /** SDK default max retry count **/
-    public static final int DEFAULT_MAX_ERROR_RETRY = 3;
-
-    /**
-     * SDK default retry policy. Amazon DynamoDB has a custom retry policy that is used when no
-     * {@link ClientConfiguration} is provided.
-     */
-    public static final RetryPolicy DEFAULT;
-
-    /* Default for DynamoDB client */
-
-    /** Default max retry count for DynamoDB client **/
-    public static final int DYNAMODB_DEFAULT_MAX_ERROR_RETRY = 10;
-
-    /** Default policy for DynamoDB client **/
-    public static final RetryPolicy DYNAMODB_DEFAULT;
-
-    /* Reusable retry policy components */
-
-    /**
-     * The SDK default retry condition, which checks for various conditions in
-     * the following order:
-     * <ul>
-     *   <li>Never retry on requests with non-repeatable content;
-     *   <li>Retry on client exceptions caused by IOException;
-     *   <li>Retry on service exceptions that are either 500 internal server
-     *       errors, 503 service unavailable errors, service throttling errors or
-     *       clock skew errors.
-     * </ul>
-     */
-    public static final RetryPolicy.RetryCondition DEFAULT_RETRY_CONDITION = new SDKDefaultRetryCondition();
-
-    /**
-     * The SDK default back-off strategy, which increases exponentially up to a max amount of delay. It also applies a larger
-     * scale factor upon service throttling exception.
-     */
-    public static final RetryPolicy.BackoffStrategy DEFAULT_BACKOFF_STRATEGY =
-            new PredefinedBackoffStrategies.SDKDefaultBackoffStrategy();
-
-    /**
-     * The SDK default back-off strategy, which increases exponentially up to a max amount of delay. It also applies a larger
-     * scale factor upon service throttling exception.
-     */
-    public static final V2CompatibleBackoffStrategy DEFAULT_BACKOFF_STRATEGY_V2 =
-            new PredefinedBackoffStrategies.SDKDefaultBackoffStrategy();
-
-    /**
-     * The default back-off strategy for DynamoDB client, which increases
-     * exponentially up to a max amount of delay. Compared to the SDK default
-     * back-off strategy, it applies a smaller scale factor.
-     */
-    public static final RetryPolicy.BackoffStrategy DYNAMODB_DEFAULT_BACKOFF_STRATEGY =
-            new PredefinedBackoffStrategies.SDKDefaultBackoffStrategy(PredefinedBackoffStrategies.DYNAMODB_DEFAULT_BASE_DELAY,
-                                                                      PredefinedBackoffStrategies.SDK_DEFAULT_THROTTLED_BASE_DELAY,
-                                                                      PredefinedBackoffStrategies.SDK_DEFAULT_MAX_BACKOFF_IN_MILLISECONDS);
-
-    static {
-        DEFAULT = getDefaultRetryPolicy();
-        DYNAMODB_DEFAULT = getDynamoDBDefaultRetryPolicy();
-    }
-
-    /**
-     * Returns the SDK default retry policy. This policy will honor the
-     * maxErrorRetry set in ClientConfiguration.
-     *
-     * @see ClientConfiguration#setMaxErrorRetry(int)
-     */
-    public static RetryPolicy getDefaultRetryPolicy() {
-        return new RetryPolicy(DEFAULT_RETRY_CONDITION,
-                               DEFAULT_BACKOFF_STRATEGY,
-                               DEFAULT_MAX_ERROR_RETRY,
-                               true);
-    }
-
-    /**
-     * Returns the default retry policy for DynamoDB client. This policy will
-     * honor the maxErrorRetry set in ClientConfiguration.
-     *
-     * @see ClientConfiguration#setMaxErrorRetry(int)
-     */
-    public static RetryPolicy getDynamoDBDefaultRetryPolicy() {
-        return new RetryPolicy(DEFAULT_RETRY_CONDITION,
-                               DYNAMODB_DEFAULT_BACKOFF_STRATEGY,
-                               DYNAMODB_DEFAULT_MAX_ERROR_RETRY,
-                               true);
-    }
-
-    /**
-     * Returns the SDK default retry policy with the specified max retry count.
-     */
-    public static RetryPolicy getDefaultRetryPolicyWithCustomMaxRetries(int maxErrorRetry) {
-        return new RetryPolicy(DEFAULT_RETRY_CONDITION,
-                               DEFAULT_BACKOFF_STRATEGY,
-                               maxErrorRetry,
-                               false);
-    }
-
-    /**
-     * Returns the default retry policy for DynamoDB client with the specified
-     * max retry count.
-     */
-    public static RetryPolicy getDynamoDBDefaultRetryPolicyWithCustomMaxRetries(int maxErrorRetry) {
-        return new RetryPolicy(DEFAULT_RETRY_CONDITION,
-                               DYNAMODB_DEFAULT_BACKOFF_STRATEGY,
-                               maxErrorRetry,
-                               false);
-    }
-
-    /**
-     * The default implementation of RetryCondition used by the SDK. User could
-     * extend this class to provide additional custom conditions.
-     * The default implementation checks for various conditions in
-     * the following order:
-     * <ul>
-     *   <li>Retry on client exceptions caused by IOException;
-     *   <li>Retry on service exceptions that are either 500 internal server
-     *       errors, 503 service unavailable errors, service throttling errors or
-     *       clock skew errors.
-     * </ul>
-     */
-    public static class SDKDefaultRetryCondition implements RetryPolicy.RetryCondition {
-
-        @Override
-        public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
-                                   AmazonClientException exception,
-                                   int retriesAttempted) {
-            // Always retry on client exceptions caused by IOException
-            if (exception.getCause() instanceof IOException) return true;
-
-            // Only retry on a subset of service exceptions
-            if (exception instanceof AmazonServiceException) {
-                AmazonServiceException ase = (AmazonServiceException)exception;
-
-                /*
-                 * For 500 internal server errors and 503 service
-                 * unavailable errors, we want to retry, but we need to use
-                 * an exponential back-off strategy so that we don't overload
-                 * a server with a flood of retries.
-                 */
-                if (RetryUtils.isRetryableServiceException(ase)) return true;
-
-                /*
-                 * Throttling is reported as a 400 error from newer services. To try
-                 * and smooth out an occasional throttling error, we'll pause and
-                 * retry, hoping that the pause is long enough for the request to
-                 * get through the next time.
-                 */
-                if (RetryUtils.isThrottlingException(ase)) return true;
-
-                /*
-                 * Clock skew exception. If it is then we will get the time offset
-                 * between the device time and the server time to set the clock skew
-                 * and then retry the request.
-                 */
-                if (RetryUtils.isClockSkewError(ase)) return true;
-            }
-
-            return false;
-        }
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/RetryPolicyAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/RetryPolicyAdapter.java
--- ./src/main/java/com/amazonaws/retry/RetryPolicyAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/RetryPolicyAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,70 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.retry.v2.RetryPolicyContext;
-
-import static com.amazonaws.util.ValidationUtils.assertNotNull;
-
-/**
- * Adapts a legacy {@link RetryPolicy} to the new {@link com.amazonaws.retry.v2.RetryPolicy}. This class is intended for internal
- * use by the SDK.
- */
-@SdkInternalApi
-public class RetryPolicyAdapter implements com.amazonaws.retry.v2.RetryPolicy {
-
-    private final RetryPolicy legacyRetryPolicy;
-    private final ClientConfiguration clientConfiguration;
-
-    public RetryPolicyAdapter(RetryPolicy legacyRetryPolicy, ClientConfiguration clientConfiguration) {
-        this.legacyRetryPolicy = assertNotNull(legacyRetryPolicy, "legacyRetryPolicy");
-        this.clientConfiguration = assertNotNull(clientConfiguration, "clientConfiguration");
-    }
-
-    @Override
-    public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-        return legacyRetryPolicy.getBackoffStrategy().delayBeforeNextRetry(
-                (AmazonWebServiceRequest) context.originalRequest(),
-                (AmazonClientException) context.exception(),
-                context.retriesAttempted());
-    }
-
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        if (context.retriesAttempted() >= getMaxErrorRetry()) {
-            return false;
-        }
-        return legacyRetryPolicy.getRetryCondition().shouldRetry(
-                (AmazonWebServiceRequest) context.originalRequest(),
-                (AmazonClientException) context.exception(),
-                context.retriesAttempted());
-    }
-
-    public RetryPolicy getLegacyRetryPolicy() {
-        return this.legacyRetryPolicy;
-    }
-
-    private int getMaxErrorRetry() {
-        if(legacyRetryPolicy.isMaxErrorRetryInClientConfigHonored() && clientConfiguration.getMaxErrorRetry() >= 0) {
-            return clientConfiguration.getMaxErrorRetry();
-        }
-        return legacyRetryPolicy.getMaxErrorRetry();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/RetryPolicy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/RetryPolicy.java
--- ./src/main/java/com/amazonaws/retry/RetryPolicy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/RetryPolicy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,235 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.annotation.Immutable;
-
-/**
- * Retry policy that can be configured on a specific service client using
- * {@link ClientConfiguration}. This class is immutable, therefore safe to be
- * shared by multiple clients.
- * 
- * @see ClientConfiguration
- * @see PredefinedRetryPolicies
- */
-@Immutable
-public final class RetryPolicy {
-
-    /**
-     * Condition on whether a request should be retried. This field
-     * should not be null.
-     */
-    private final RetryCondition retryCondition;
-    
-    /**
-     * Back-off strategy to control the sleep time between retry attempts. This
-     * field should not be null.
-     */
-    private final BackoffStrategy backoffStrategy;
-    
-    /**
-     * Non-negative integer indicating the max retry count.
-     */
-    private final int maxErrorRetry;
-    
-    /**
-     * Whether this retry policy should honor the max error retry set in ClientConfiguration.
-     * @see ClientConfiguration#setMaxErrorRetry(int)
-     */
-    private final boolean honorMaxErrorRetryInClientConfig;
-
-    /**
-     * Constructs a new retry policy. See {@link PredefinedRetryPolicies} for
-     * some pre-defined policy components, and also the default policies used by
-     * SDK.
-     * 
-     * @param retryCondition
-     *            Retry condition on whether a specific request and exception
-     *            should be retried. If null value is specified, the SDK'
-     *            default retry condition is used.
-     * @param backoffStrategy
-     *            Back-off strategy for controlling how long the next retry
-     *            should wait. If null value is specified, the SDK' default
-     *            exponential back-off strategy is used.
-     * @param maxErrorRetry
-     *            Maximum number of retry attempts for failed requests.
-     * @param honorMaxErrorRetryInClientConfig
-     *            Whether this retry policy should honor the max error retry set
-     *            by {@link ClientConfiguration#setMaxErrorRetry(int)}
-     * @see ClientConfiguration
-     * @see PredefinedRetryPolicies
-     */
-    public RetryPolicy(RetryCondition retryCondition,
-                       BackoffStrategy backoffStrategy,
-                       int maxErrorRetry,
-                       boolean honorMaxErrorRetryInClientConfig) {
-        if (retryCondition == null) {
-            retryCondition = PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION;
-        }
-        if (backoffStrategy == null) {
-            backoffStrategy = PredefinedRetryPolicies.DEFAULT_BACKOFF_STRATEGY;
-        }
-        if (maxErrorRetry < 0) {
-            throw new IllegalArgumentException("Please provide a non-negative value for maxErrorRetry.");
-        }
-        
-        this.retryCondition = retryCondition;
-        this.backoffStrategy = backoffStrategy;
-        this.maxErrorRetry = maxErrorRetry;
-        this.honorMaxErrorRetryInClientConfig = honorMaxErrorRetryInClientConfig;
-    };
-
-    /**
-     * Returns the retry condition included in this retry policy.
-     * 
-     * @return The retry condition included in this retry policy.
-     */
-    public RetryCondition getRetryCondition() {
-        return retryCondition;
-    }
-
-    /**
-     * Returns the back-off strategy included in this retry policy.
-     * 
-     * @return The back-off strategy included in this retry policy.
-     */
-    public BackoffStrategy getBackoffStrategy() {
-        return backoffStrategy;
-    }
-
-    /**
-     * Returns the maximum number of retry attempts.
-     * 
-     * @return The maximum number of retry attempts.
-     */
-    public int getMaxErrorRetry() {
-        return maxErrorRetry;
-    }
-    
-    /**
-     * Returns whether this retry policy should honor the max error retry set in
-     * ClientConfiguration.
-     * 
-     * @return Whether this retry policy should honor the max error retry set in
-     *         ClientConfiguration
-     * @see ClientConfiguration#setMaxErrorRetry(int)
-     */
-    public boolean isMaxErrorRetryInClientConfigHonored() {
-        return honorMaxErrorRetryInClientConfig;
-    }
-    
-    /**
-     * The hook for providing custom condition on whether a failed request
-     * should be retried.
-     */
-    public interface RetryCondition {
-        RetryCondition NO_RETRY_CONDITION = new RetryCondition() {
-            @Override
-            public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
-                                       AmazonClientException exception,
-                                       int retriesAttempted) {
-                return false;
-            }
-        };
-
-        /**
-         * Returns whether a failed request should be retried according to the
-         * given request context. In the following circumstances, the request
-         * will fail directly without consulting this method:
-         * <ul>
-         *   <li> if it has already reached the max retry limit,
-         *   <li> if the request contains non-repeatable content,
-         *   <li> if any RuntimeException or Error is thrown when executing the request.
-         * </ul>
-         * 
-         * @param originalRequest
-         *            The original request object being executed. For
-         *            performance reason, this object is not a defensive copy,
-         *            and caller should not attempt to modify its data.
-         * @param exception
-         *            The exception from the failed request, represented as an
-         *            AmazonClientException object. There are two types of
-         *            exception that will be passed to this method:
-         *            <ul>
-         *            <li>AmazonServiceException (sub-class of
-         *            AmazonClientException) indicating a service error
-         *            <li>AmazonClientException caused by an IOException when
-         *            executing the HTTP request.
-         *            </ul>
-         *            Any other exceptions are regarded as unexpected failures
-         *            and are thrown immediately without any retry. For
-         *            performance reason, this object is not a defensive copy,
-         *            and caller should not attempt to modify its data.
-         * @param retriesAttempted
-         *            The number of times the current request has been
-         *            attempted.
-         * 
-         * @return True if the failed request should be retried.
-         */
-        boolean shouldRetry(AmazonWebServiceRequest originalRequest,
-                                   AmazonClientException exception,
-                                   int retriesAttempted);
-        
-    }
-
-    /**
-     * The hook for providing custom back-off strategy to control the sleep time
-     * between retries.
-     */
-    public interface BackoffStrategy {
-        RetryPolicy.BackoffStrategy NO_DELAY = new BackoffStrategy() {
-            @Override
-            public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
-                                             AmazonClientException exception,
-                                             int retriesAttempted) {
-                return 0;
-            }
-        };
-
-        /**
-         * Returns the delay (in milliseconds) before next retry attempt.
-         * 
-         * @param originalRequest
-         *            The original request object being executed. For
-         *            performance reason, this object is not a defensive copy,
-         *            and caller should not attempt to modify its data.
-         * @param exception
-         *            The exception from the failed request, represented as an
-         *            AmazonClientException object. There are two types of
-         *            exception that will be passed to this method:
-         *            <ul>
-         *              <li>AmazonServiceException (sub-class of
-         *                  AmazonClientException) indicating a service error
-         *              <li>AmazonClientException caused by an IOException when
-         *                  executing the HTTP request.
-         *            </ul>
-         *            Any other exceptions are regarded as unexpected failures
-         *            and are thrown immediately without any retry. For
-         *            performance reason, this object is not a defensive copy,
-         *            and caller should not attempt to modify its data.
-         * @param retriesAttempted
-         *            The number of times the current request has been attempted
-         *            (not including the next attempt after the delay).
-         * 
-         * @return The delay (in milliseconds) before next retry attempt.
-         */
-        long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
-                                         AmazonClientException exception,
-                                         int retriesAttempted);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/RetryUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/RetryUtils.java
--- ./src/main/java/com/amazonaws/retry/RetryUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/RetryUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,144 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.SdkBaseException;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.http.HttpStatus;
-
-public class RetryUtils {
-
-    static final Set<String> THROTTLING_ERROR_CODES = new HashSet<String>(9);
-    static final Set<String> CLOCK_SKEW_ERROR_CODES = new HashSet<String>(6);
-    static final Set<String> RETRYABLE_ERROR_CODES = new HashSet<String>(1);
-    static final Set<Integer> RETRYABLE_STATUS_CODES = new HashSet<Integer>(4);
-
-    static {
-        THROTTLING_ERROR_CODES.add("Throttling");
-        THROTTLING_ERROR_CODES.add("ThrottlingException");
-        THROTTLING_ERROR_CODES.add("ThrottledException");
-        THROTTLING_ERROR_CODES.add("ProvisionedThroughputExceededException");
-        THROTTLING_ERROR_CODES.add("SlowDown");
-        THROTTLING_ERROR_CODES.add("TooManyRequestsException");
-        THROTTLING_ERROR_CODES.add("RequestLimitExceeded");
-        THROTTLING_ERROR_CODES.add("BandwidthLimitExceeded");
-        THROTTLING_ERROR_CODES.add("RequestThrottled");
-
-        CLOCK_SKEW_ERROR_CODES.add("RequestTimeTooSkewed");
-        CLOCK_SKEW_ERROR_CODES.add("RequestExpired");
-        CLOCK_SKEW_ERROR_CODES.add("InvalidSignatureException");
-        CLOCK_SKEW_ERROR_CODES.add("SignatureDoesNotMatch");
-        CLOCK_SKEW_ERROR_CODES.add("AuthFailure");
-        CLOCK_SKEW_ERROR_CODES.add("RequestInTheFuture");
-
-        RETRYABLE_ERROR_CODES.add("PriorRequestNotComplete");
-
-        RETRYABLE_STATUS_CODES.add(HttpStatus.SC_INTERNAL_SERVER_ERROR);
-        RETRYABLE_STATUS_CODES.add(HttpStatus.SC_BAD_GATEWAY);
-        RETRYABLE_STATUS_CODES.add(HttpStatus.SC_SERVICE_UNAVAILABLE);
-        RETRYABLE_STATUS_CODES.add(HttpStatus.SC_GATEWAY_TIMEOUT);
-    }
-
-    /**
-     * @deprecated By {@link RetryUtils#isRetryableServiceException(SdkBaseException)}
-     */
-    @Deprecated
-    public static boolean isRetryableServiceException(AmazonServiceException exception) {
-        return isRetryableServiceException((SdkBaseException) exception);
-    }
-
-    /**
-     * Returns true if the specified exception is a retryable service side exception.
-     *
-     * @param exception The exception to test.
-     * @return True if the exception resulted from a retryable service error, otherwise false.
-     */
-    public static boolean isRetryableServiceException(SdkBaseException exception) {
-        if (!isAse(exception)) {
-            return false;
-        }
-        AmazonServiceException ase = toAse(exception);
-        return RETRYABLE_STATUS_CODES.contains(ase.getStatusCode()) || RETRYABLE_ERROR_CODES.contains(ase.getErrorCode());
-    }
-
-    /**
-     * @deprecated In favor of {@link RetryUtils#isThrottlingException(SdkBaseException)}
-     */
-    @Deprecated
-    public static boolean isThrottlingException(AmazonServiceException exception) {
-        return isThrottlingException((SdkBaseException) exception);
-    }
-
-    /**
-     * Returns true if the specified exception is a throttling error.
-     *
-     * @param exception The exception to test.
-     * @return True if the exception resulted from a throttling error message from a service, otherwise false.
-     */
-    public static boolean isThrottlingException(SdkBaseException exception) {
-        if (!isAse(exception)) {
-            return false;
-        }
-        final AmazonServiceException ase = toAse(exception);
-        return THROTTLING_ERROR_CODES.contains(ase.getErrorCode()) || ase.getStatusCode() == 429;
-    }
-
-    /**
-     * @deprecated By {@link RetryUtils#isRequestEntityTooLargeException(SdkBaseException)}
-     */
-    @Deprecated
-    public static boolean isRequestEntityTooLargeException(AmazonServiceException exception) {
-        return isRequestEntityTooLargeException((SdkBaseException) exception);
-    }
-
-    /**
-     * Returns true if the specified exception is a request entity too large error.
-     *
-     * @param exception The exception to test.
-     * @return True if the exception resulted from a request entity too large error message from a service, otherwise false.
-     */
-    public static boolean isRequestEntityTooLargeException(SdkBaseException exception) {
-        return isAse(exception) && toAse(exception).getStatusCode() == HttpStatus.SC_REQUEST_TOO_LONG;
-    }
-
-    /**
-     * @deprecated By {@link RetryUtils#isClockSkewError(SdkBaseException)}
-     */
-    @Deprecated
-    public static boolean isClockSkewError(AmazonServiceException exception) {
-        return isClockSkewError((SdkBaseException) exception);
-    }
-
-    /**
-     * Returns true if the specified exception is a clock skew error.
-     *
-     * @param exception The exception to test.
-     * @return True if the exception resulted from a clock skews error message from a service, otherwise false.
-     */
-    public static boolean isClockSkewError(SdkBaseException exception) {
-        return isAse(exception) && CLOCK_SKEW_ERROR_CODES.contains(toAse(exception).getErrorCode());
-    }
-
-    private static boolean isAse(SdkBaseException e) {
-        return e instanceof AmazonServiceException;
-    }
-
-    private static AmazonServiceException toAse(SdkBaseException e) {
-        return (AmazonServiceException) e;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/AndRetryCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/AndRetryCondition.java
--- ./src/main/java/com/amazonaws/retry/v2/AndRetryCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/AndRetryCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static com.amazonaws.util.ValidationUtils.assertNotEmpty;
-
-/**
- * Composite {@link RetryCondition} that evaluates to true when all contained retry conditions evaluate to true.
- */
-public class AndRetryCondition implements RetryCondition {
-
-    private List<RetryCondition> conditions = new ArrayList<RetryCondition>();
-
-    public AndRetryCondition(RetryCondition... conditions) {
-        Collections.addAll(this.conditions, assertNotEmpty(conditions, "conditions"));
-    }
-
-    /**
-     * @return True if all conditions are true, false otherwise.
-     */
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        for (RetryCondition retryCondition : conditions) {
-            if (!retryCondition.shouldRetry(context)) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/BackoffStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/BackoffStrategy.java
--- ./src/main/java/com/amazonaws/retry/v2/BackoffStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/BackoffStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-/**
- * Super interface for {@link RetryPolicy} that defines a strategy for backing off between retries.
- */
-public interface BackoffStrategy {
-
-    /**
-     * Compute the delay before the next retry request. This strategy is only consulted when there will be a next retry.
-     *
-     * @param context Context about the state of the last request and information about the number of requests made.
-     * @return Amount of time in milliseconds to wait before the next attempt. Must be non-negative (can be zero).
-     */
-    long computeDelayBeforeNextRetry(RetryPolicyContext context);
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/FixedDelayBackoffStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/FixedDelayBackoffStrategy.java
--- ./src/main/java/com/amazonaws/retry/v2/FixedDelayBackoffStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/FixedDelayBackoffStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,34 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import static com.amazonaws.util.ValidationUtils.assertIsPositive;
-
-/**
- * Simple backoff strategy that always uses a fixed delay.
- */
-public class FixedDelayBackoffStrategy implements BackoffStrategy {
-
-    private final int fixedBackoff;
-
-    public FixedDelayBackoffStrategy(int fixedBackoff) {
-        this.fixedBackoff = assertIsPositive(fixedBackoff, "fixedBackoff");
-    }
-
-    @Override
-    public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-        return fixedBackoff;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/MaxNumberOfRetriesCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/MaxNumberOfRetriesCondition.java
--- ./src/main/java/com/amazonaws/retry/v2/MaxNumberOfRetriesCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/MaxNumberOfRetriesCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,34 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import static com.amazonaws.util.ValidationUtils.assertIsPositive;
-
-/**
- * Simple retry condition that allows retries up to a certain max number of retries.
- */
-public class MaxNumberOfRetriesCondition implements RetryCondition {
-
-    private final int maxNumberOfRetries;
-
-    public MaxNumberOfRetriesCondition(int maxNumberOfRetries) {
-        this.maxNumberOfRetries = assertIsPositive(maxNumberOfRetries, "maxNumberOfRetries");
-    }
-
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        return context.retriesAttempted() < maxNumberOfRetries;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/OrRetryCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/OrRetryCondition.java
--- ./src/main/java/com/amazonaws/retry/v2/OrRetryCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/OrRetryCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,44 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Composite retry condition that evaluates to true if any containing condition evaluates to true.
- */
-public class OrRetryCondition implements RetryCondition {
-
-    private List<RetryCondition> conditions = new ArrayList<RetryCondition>();
-
-    public OrRetryCondition(RetryCondition... conditions) {
-        Collections.addAll(this.conditions, conditions);
-    }
-
-    /**
-     * @return True if any condition returns true. False otherwise.
-     */
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        for (RetryCondition retryCondition : conditions) {
-            if (retryCondition.shouldRetry(context)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/RetryCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryCondition.java
--- ./src/main/java/com/amazonaws/retry/v2/RetryCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-/**
- * Super interface for {@link RetryPolicy} used to define when a request should be retried.
- */
-public interface RetryCondition {
-
-    /**
-     * Determine whether a request should or should not be retried.
-     *
-     * @param context Context about the state of the last request and information about the number of requests made.
-     * @return True if the request should be retried, false if not.
-     */
-    boolean shouldRetry(RetryPolicyContext context);
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/RetryOnExceptionsCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryOnExceptionsCondition.java
--- ./src/main/java/com/amazonaws/retry/v2/RetryOnExceptionsCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryOnExceptionsCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,79 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.amazonaws.util.ValidationUtils.assertNotNull;
-
-/**
- * Retry condition implementation that retries if the exception or the cause of the exception matches the classes defined.
- */
-public class RetryOnExceptionsCondition implements RetryCondition {
-
-    private final List<Class<? extends Exception>> exceptionsToRetryOn;
-
-    /**
-     * @param exceptionsToRetryOn Exception classes to retry on.
-     */
-    public RetryOnExceptionsCondition(List<Class<? extends Exception>> exceptionsToRetryOn) {
-        this.exceptionsToRetryOn = new ArrayList<Class<? extends Exception>>(
-                assertNotNull(exceptionsToRetryOn, "exceptionsToRetryOn"));
-    }
-
-    /**
-     * @param context Context about the state of the last request and information about the number of requests made.
-     * @return True if the exception class matches one of the whitelisted exceptions or if the cause of the exception matches the
-     * whitelisted exception.
-     */
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        if (context.exception() != null) {
-            for (Class<? extends Exception> exceptionClass : exceptionsToRetryOn) {
-                if (exceptionMatches(context, exceptionClass)) {
-                    return true;
-                }
-                // Note that we check the wrapped exception too because for things like SocketException or IOException
-                // we wrap them in an SdkClientException before throwing.
-                if (wrappedCauseMatches(context, exceptionClass)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @param context        Context containing exception.
-     * @param exceptionClass Expected exception class.
-     * @return True if the exception in the context matches the provided class.
-     */
-    private boolean exceptionMatches(RetryPolicyContext context, Class<? extends Exception> exceptionClass) {
-        return context.exception().getClass().equals(exceptionClass);
-    }
-
-    /**
-     * @param context        Context containing exception.
-     * @param exceptionClass Expected exception class.
-     * @return True if the cause of the exception in the context matches the provided class.
-     */
-    private boolean wrappedCauseMatches(RetryPolicyContext context, Class<? extends Exception> exceptionClass) {
-        if (context.exception().getCause() == null) {
-            return false;
-        }
-        return context.exception().getCause().getClass().equals(exceptionClass);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/RetryOnStatusCodeCondition.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryOnStatusCodeCondition.java
--- ./src/main/java/com/amazonaws/retry/v2/RetryOnStatusCodeCondition.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryOnStatusCodeCondition.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,50 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.amazonaws.util.ValidationUtils.assertNotNull;
-
-/**
- * Retry condition implementation that retries if the HTTP status code matches one of the provided status codes.
- */
-public class RetryOnStatusCodeCondition implements RetryCondition {
-
-    private final List<Integer> statusCodesToRetryOn;
-
-    public RetryOnStatusCodeCondition(List<Integer> statusCodesToRetryOn) {
-        this.statusCodesToRetryOn = new ArrayList<Integer>(
-                assertNotNull(statusCodesToRetryOn, "statusCodesToRetryOn"));
-    }
-
-    /**
-     * @param context Context about the state of the last request and information about the number of requests made.
-     * @return True if the HTTP status code matches one of the provided status codes. False if it doesn't match or the request
-     * failed for reasons other than an exceptional HTTP response (i.e. IOException).
-     */
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        if (context.httpStatusCode() != null) {
-            for (Integer statusCode : statusCodesToRetryOn) {
-                if (statusCode.equals(context.httpStatusCode())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/RetryPolicyContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryPolicyContext.java
--- ./src/main/java/com/amazonaws/retry/v2/RetryPolicyContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryPolicyContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,138 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import com.amazonaws.Request;
-import com.amazonaws.SdkBaseException;
-import com.amazonaws.annotation.Immutable;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.handlers.HandlerContextKey;
-
-/**
- * Contains useful information about a failed request that can be used to make retry and backoff decisions. See {@link
- * RetryPolicy}.
- */
-@Immutable
-public class RetryPolicyContext {
-
-    private final Object originalRequest;
-    private final Request<?> request;
-    private final SdkBaseException exception;
-    private final int retriesAttempted;
-    private final Integer httpStatusCode;
-
-    private RetryPolicyContext(Object originalRequest,
-                               Request<?> request,
-                               SdkBaseException exception,
-                               int retriesAttempted,
-                               Integer httpStatusCode) {
-        this.originalRequest = originalRequest;
-        this.request = request;
-        this.exception = exception;
-        this.retriesAttempted = retriesAttempted;
-        this.httpStatusCode = httpStatusCode;
-    }
-
-    /**
-     * @return The original request passed to the client method for an operation.
-     */
-    public Object originalRequest() {
-        return this.originalRequest;
-    }
-
-    /**
-     * @return The marshalled request. See {@link Request#addHandlerContext(HandlerContextKey, Object)} for a mechanism to store
-     * request level state across invocations of the retry policy.
-     */
-    public Request<?> request() {
-        return this.request;
-    }
-
-    /**
-     * @return The previous exception (may be a client or a service exception).
-     */
-    public SdkBaseException exception() {
-        return this.exception;
-    }
-
-    /**
-     * @return Number of retries attempted thus far.
-     */
-    public int retriesAttempted() {
-        return this.retriesAttempted;
-    }
-
-    /**
-     * @return The total number of requests made thus far.
-     */
-    public int totalRequests() {
-        return retriesAttempted() + 1;
-    }
-
-    /**
-     * @return HTTP status code of response. May be null if no response was received from the service.
-     */
-    public Integer httpStatusCode() {
-        return this.httpStatusCode;
-    }
-
-    @SdkInternalApi
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    @SdkInternalApi
-    public static class Builder {
-
-        private Object originalRequest;
-        private Request<?> request;
-        private SdkBaseException exception;
-        private int retriesAttempted;
-        private Integer httpStatusCode;
-
-        private Builder() {
-        }
-
-        public Builder originalRequest(Object originalRequest) {
-            this.originalRequest = originalRequest;
-            return this;
-        }
-
-        public Builder request(Request<?> request) {
-            this.request = request;
-            return this;
-        }
-
-        public Builder exception(SdkBaseException exception) {
-            this.exception = exception;
-            return this;
-        }
-
-        public Builder retriesAttempted(int retriesAttempted) {
-            this.retriesAttempted = retriesAttempted;
-            return this;
-        }
-
-        public Builder httpStatusCode(Integer httpStatusCode) {
-            this.httpStatusCode = httpStatusCode;
-            return this;
-        }
-
-        public RetryPolicyContext build() {
-            return new RetryPolicyContext(originalRequest, request, exception, retriesAttempted, httpStatusCode);
-        }
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/RetryPolicy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryPolicy.java
--- ./src/main/java/com/amazonaws/retry/v2/RetryPolicy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/RetryPolicy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,21 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-/**
- * Aggregate interface combining a {@link RetryCondition} and {@link BackoffStrategy} into a single policy.
- */
-public interface RetryPolicy extends RetryCondition, BackoffStrategy {
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/v2/SimpleRetryPolicy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/SimpleRetryPolicy.java
--- ./src/main/java/com/amazonaws/retry/v2/SimpleRetryPolicy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/v2/SimpleRetryPolicy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,41 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry.v2;
-
-import static com.amazonaws.util.ValidationUtils.assertNotNull;
-
-/**
- * Implementation of {@link RetryPolicy} that combines an individual {@link RetryCondition} and {@link BackoffStrategy}.
- */
-public class SimpleRetryPolicy implements RetryPolicy {
-
-    private final RetryCondition retryCondition;
-    private final BackoffStrategy backoffStrategy;
-
-    public SimpleRetryPolicy(RetryCondition retryCondition, BackoffStrategy backoffStrategy) {
-        this.retryCondition = assertNotNull(retryCondition, "retryCondition");
-        this.backoffStrategy = assertNotNull(backoffStrategy, "backoffStrategy");
-    }
-
-    @Override
-    public long computeDelayBeforeNextRetry(RetryPolicyContext context) {
-        return backoffStrategy.computeDelayBeforeNextRetry(context);
-    }
-
-    @Override
-    public boolean shouldRetry(RetryPolicyContext context) {
-        return retryCondition.shouldRetry(context);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategyAdapter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategyAdapter.java
--- ./src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategyAdapter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategyAdapter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,39 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.AmazonClientException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.retry.v2.RetryPolicyContext;
-
-/**
- * Adapts the legacy backoff strategy to the new v2 backoff strategy. Strategies that extend this can be used in both legacy and
- * v2 retry policies.
- */
-@SdkInternalApi
-abstract class V2CompatibleBackoffStrategyAdapter implements V2CompatibleBackoffStrategy {
-
-    @Override
-    public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
-                                     AmazonClientException exception,
-                                     int retriesAttempted) {
-        return computeDelayBeforeNextRetry(RetryPolicyContext.builder()
-                                            .originalRequest(originalRequest)
-                                            .exception(exception)
-                                            .retriesAttempted(retriesAttempted)
-                                            .build());
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategy.java
--- ./src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/retry/V2CompatibleBackoffStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,23 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.retry;
-
-import com.amazonaws.retry.v2.BackoffStrategy;
-
-/**
- * Adapter interface for backoff strategies that can be used in both legacy RetryPolicies and the new V2 retry policy.
- */
-public interface V2CompatibleBackoffStrategy extends RetryPolicy.BackoffStrategy, BackoffStrategy {
-}
diff -Nau8r ./src/main/java/com/amazonaws/sdk/versionInfo.properties /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/sdk/versionInfo.properties
--- ./src/main/java/com/amazonaws/sdk/versionInfo.properties	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/sdk/versionInfo.properties	1969-12-31 16:00:00.000000000 -0800
@@ -1,4 +0,0 @@
-#Fri Mar 16 21:28:39 UTC 2018
-platform=java
-version=1.11.297
-internalVersion=5773132671
diff -Nau8r ./src/main/java/com/amazonaws/ServiceNameFactory.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ServiceNameFactory.java
--- ./src/main/java/com/amazonaws/ServiceNameFactory.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/ServiceNameFactory.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import com.amazonaws.internal.config.HttpClientConfig;
-import com.amazonaws.internal.config.InternalConfig;
-
-/**
- * An internal service name factory.
- */
-enum ServiceNameFactory {
-    ;
-
-    /**
-     * Returns the serviceName config for the specified service client, or null
-     * if no explicit config is found.
-     */
-    static String getServiceName(String httpClientName) {
-        InternalConfig config = InternalConfig.Factory.getInternalConfig();
-        HttpClientConfig clientConfig = config.getHttpClientConfig(httpClientName);
-        return clientConfig == null ? null : clientConfig.getServiceName();
-    }
-
-    /**
-     * Returns the regionMetadataServiceName config for the specified service
-     * client, or null if no explicit config is found.
-     */
-    static String getServiceNameInRegionMetadata(String httpClientName) {
-        InternalConfig config = InternalConfig.Factory.getInternalConfig();
-        HttpClientConfig clientConfig = config.getHttpClientConfig(httpClientName);
-        return clientConfig == null ? null : clientConfig.getRegionMetadataServiceName();
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/SignableRequest.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SignableRequest.java
--- ./src/main/java/com/amazonaws/SignableRequest.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SignableRequest.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,62 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import java.io.InputStream;
-
-/**
- * Represents a sign-able request being sent to an Amazon Web Service, including the
- * parameters being sent as part of the request, the endpoint to which the
- * request should be sent, etc.
- * <p>
- * This class is only intended for internal use inside the AWS client libraries.
- * Callers shouldn't ever interact directly with objects of this class.
- *
- * @param <T>
- *            The type of original, user facing request represented by this
- *            request.
- */
-public interface SignableRequest<T> extends ImmutableRequest<T> {
-
-    /**
-     * Sets the specified header for this request.
-     *
-     * @param name
-     *            The name of the header to set.
-     * @param value
-     *            The header's value.
-     */
-    void addHeader(String name, String value);
-
-    /**
-     * Adds the specified request parameter to this request.
-     *
-     * @param name
-     *            The name of the request parameter.
-     * @param value
-     *            The value of the request parameter.
-     */
-    void addParameter(String name, String value);
-
-    /**
-     * Sets the optional stream containing the payload data to include for this
-     * request. This is used, for example, for S3 chunk encoding.
-     *
-     * @param content
-     *            The optional stream containing the payload data to include for
-     *            this request.
-     */
-    void setContent(InputStream content);
-}
diff -Nau8r ./src/main/java/com/amazonaws/SystemDefaultDnsResolver.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SystemDefaultDnsResolver.java
--- ./src/main/java/com/amazonaws/SystemDefaultDnsResolver.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/SystemDefaultDnsResolver.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Default dns resolver that uses {@link java.net.InetAddress#getAllByName(String)}
- * to resolve hosts to ip addresses
- */
-public class SystemDefaultDnsResolver implements DnsResolver {
-    @Override
-    public InetAddress[] resolve(String host) throws UnknownHostException {
-        return InetAddress.getAllByName(host);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/AbstractErrorUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/AbstractErrorUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/AbstractErrorUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/AbstractErrorUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,69 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import java.lang.reflect.Constructor;
-
-import com.amazonaws.AmazonServiceException;
-
-public abstract class AbstractErrorUnmarshaller<T> implements Unmarshaller<AmazonServiceException, T> {
-
-    /**
-     * The type of AmazonServiceException that will be instantiated. Subclasses
-     * specialized for a specific type of exception can control this through the
-     * protected constructor.
-     */
-    protected final Class<? extends AmazonServiceException> exceptionClass;
-
-    /**
-     * Constructs a new error unmarshaller that will unmarshall error responses
-     * into AmazonServiceException objects.
-     */
-    public AbstractErrorUnmarshaller() {
-        this(AmazonServiceException.class);
-    }
-
-    /**
-     * Constructs a new error unmarshaller that will unmarshall error responses
-     * into objects of the specified class, extending AmazonServiceException.
-     * 
-     * @param exceptionClass
-     *            The subclass of AmazonServiceException which will be
-     *            instantiated and populated by this class.
-     */
-    public AbstractErrorUnmarshaller(Class<? extends AmazonServiceException> exceptionClass) {
-        this.exceptionClass = exceptionClass;
-    }
-
-    /**
-     * Constructs a new exception object of the type specified in this class's
-     * constructor and sets the specified error message.
-     * 
-     * @param message
-     *            The error message to set in the new exception object.
-     * 
-     * @return A new exception object of the type specified in this class's
-     *         constructor and sets the specified error message.
-     * 
-     * @throws Exception
-     *             If there are any problems using reflection to invoke the
-     *             exception class's constructor.
-     */
-    protected AmazonServiceException newException(String message) throws Exception {
-        Constructor<? extends AmazonServiceException> constructor = exceptionClass.getConstructor(String.class);
-        return constructor.newInstance(message);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/JsonErrorUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/JsonErrorUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/JsonErrorUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/JsonErrorUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,66 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.annotation.ThreadSafe;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.PropertyNamingStrategy.PascalCaseStrategy;
-
-/**
- * Unmarshaller for JSON error responses from AWS services.
- */
-@SdkInternalApi
-@ThreadSafe
-public class JsonErrorUnmarshaller extends AbstractErrorUnmarshaller<JsonNode> {
-
-    public static final JsonErrorUnmarshaller DEFAULT_UNMARSHALLER = new JsonErrorUnmarshaller(
-            AmazonServiceException.class, null);
-
-    private static final ObjectMapper MAPPER = new ObjectMapper().configure(
-            DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).setPropertyNamingStrategy(
-            new PascalCaseStrategy());
-
-    private final String handledErrorCode;
-
-    /**
-     * @param exceptionClass   Exception class this unmarshaller will attempt to deserialize error response into
-     * @param handledErrorCode AWS error code that this unmarshaller handles. Pass null to handle all exceptions
-     */
-    public JsonErrorUnmarshaller(Class<? extends AmazonServiceException> exceptionClass, String handledErrorCode) {
-        super(exceptionClass);
-        this.handledErrorCode = handledErrorCode;
-    }
-
-    @Override
-    public AmazonServiceException unmarshall(JsonNode jsonContent) throws Exception {
-        return MAPPER.treeToValue(jsonContent, exceptionClass);
-    }
-
-    /**
-     * @param actualErrorCode Actual AWS error code found in the error response.
-     * @return True if the actualErrorCode can be handled by this unmarshaller, false otherwise
-     */
-    public boolean matchErrorCode(String actualErrorCode) {
-        if (handledErrorCode == null) {
-            return true;
-        }
-        return handledErrorCode.equals(actualErrorCode);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/JsonUnmarshallerContextImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/JsonUnmarshallerContextImpl.java
--- ./src/main/java/com/amazonaws/transform/JsonUnmarshallerContextImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/JsonUnmarshallerContextImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,334 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
-import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
-import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;
-import static com.fasterxml.jackson.core.JsonToken.START_ARRAY;
-import static com.fasterxml.jackson.core.JsonToken.START_OBJECT;
-
-import com.amazonaws.http.HttpResponse;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-
-public class JsonUnmarshallerContextImpl extends JsonUnmarshallerContext {
-    /** The current JsonToken that the private JsonParser is currently pointing to. **/
-    private JsonToken currentToken;
-
-    /** A cache of the next token if it has been peeked ahead. **/
-    private JsonToken nextToken;
-
-    private final JsonParser jsonParser;
-
-    private String currentHeader;
-
-    /**
-     * A stack of JsonFieldTokenPair objects that indicates the current state of the context.
-     * For example, if we have a JSON object:
-     * {
-     *   A :
-     *     {
-     *       B : [
-     *         {
-     *           C : {
-     *             D : E
-     *           }
-     *         },
-     *       ]
-     *     }
-     * }
-     * When the parser points to "D", the state of this stack should be (from top to bottom):
-     *  [ (C, START_OBJECT), (B, START_ARRAY), (A, START_OBJECT) ]
-     */
-    private final Stack<JsonFieldTokenPair> stack = new Stack<JsonFieldTokenPair>();
-
-    /**
-     * The name of the field that is currently being parsed. This value is
-     * nulled out when the parser reaches into the object/array structure of the
-     * corresponding value, and then it will be pushed into the stack after
-     * wrapped into a JsonFieldTokenPair object with the START_OBJECT or
-     * START_ARRAY token following it.
-     * So in the same example as shown above:
-     *   (1) when the parser moves from "C" to "{", (currentField, START_OBJECT)
-     *       will be pushed into the stack and currentField will be set null;
-     *   (2) but when it moves from "{" to "C", nothing will be pushed into the
-     *       stack and only currentField will be updated from null to "D".
-     */
-    private String currentField;
-
-    /**
-     * This string is used to cache the parent element that was just parsed,
-     * after it is removed from the stack.
-     */
-    private String lastParsedParentElement;
-
-    private Map<String, String> metadata = new HashMap<String, String>();
-
-    private final HttpResponse httpResponse;
-
-    private final Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> unmarshallerMap;
-
-    private final Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customUnmarshallerMap;
-
-    public JsonUnmarshallerContextImpl(JsonParser jsonParser,
-                                       Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> mapper,
-                                       HttpResponse httpResponse) {
-        this(jsonParser,
-             mapper,
-             Collections.<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>>emptyMap(),
-             httpResponse);
-    }
-
-    public JsonUnmarshallerContextImpl(JsonParser jsonParser,
-                                       Map<Class<?>, Unmarshaller<?, JsonUnmarshallerContext>> mapper,
-                                       Map<UnmarshallerType, Unmarshaller<?, JsonUnmarshallerContext>> customUnmarshallerMap,
-                                       HttpResponse httpResponse) {
-        this.jsonParser = jsonParser;
-        this.unmarshallerMap = mapper;
-        this.customUnmarshallerMap = customUnmarshallerMap;
-        this.httpResponse = httpResponse;
-    }
-
-    @Override
-    public String getHeader(String header) {
-        if (httpResponse == null) return null;
-
-        return httpResponse.getHeaders().get(header);
-    }
-
-    @Override
-    public HttpResponse getHttpResponse() {
-        return httpResponse;
-    }
-
-    @Override
-    public int getCurrentDepth() {
-        int depth = stack.size();
-        if (currentField != null) depth++;
-        return depth;
-    }
-
-    @Override
-    public String readText() throws IOException {
-
-        if (isInsideResponseHeader()) {
-            return getHeader(currentHeader);
-        }
-        return readCurrentJsonTokenValue();
-    }
-
-    private String readCurrentJsonTokenValue() throws IOException {
-        switch (currentToken) {
-        case VALUE_STRING:
-            String text = jsonParser.getText();
-            return text;
-        case VALUE_FALSE: return "false";
-        case VALUE_TRUE: return "true";
-        case VALUE_NULL: return null;
-        case VALUE_NUMBER_FLOAT:
-        case VALUE_NUMBER_INT:
-            return jsonParser.getNumberValue().toString();
-        case FIELD_NAME:
-            return jsonParser.getText();
-        default:
-            throw new RuntimeException(
-                    "We expected a VALUE token but got: " + currentToken);
-        }
-    }
-
-    @Override
-    public boolean isInsideResponseHeader() {
-        return currentToken == null && nextToken == null;
-    }
-
-    @Override
-    public boolean isStartOfDocument() {
-        return jsonParser == null || jsonParser.getCurrentToken() == null;
-    }
-
-    @Override
-    public boolean testExpression(String expression) {
-        if (expression.equals(".")) {
-            return true;
-        } else {
-            if (currentField != null) {
-                return currentField.equals(expression);
-            } else {
-                return (!stack.isEmpty())
-                        && stack.peek().getField().equals(expression);
-            }
-        }
-    }
-
-    @Override
-    public String getCurrentParentElement() {
-        String parentElement;
-        if (currentField != null) {
-            parentElement = currentField;
-        } else if ( !stack.isEmpty() ) {
-            parentElement = stack.peek().getField();
-        } else {
-            parentElement = "";
-        }
-        return parentElement;
-    }
-
-    @Override
-    public boolean testExpression(String expression, int stackDepth) {
-        if (expression.equals(".")) {
-            return true;
-        } else {
-            return testExpression(expression)
-                    && stackDepth == getCurrentDepth();
-        }
-    }
-
-    @Override
-    public JsonToken nextToken() throws IOException {
-        // Use the value from the nextToken field if
-        // we've already populated it to peek ahead.
-        JsonToken token = (nextToken != null) ?
-                nextToken : jsonParser.nextToken();
-
-        this.currentToken = token;
-        nextToken = null;
-
-        updateContext();
-        return token;
-    }
-
-    @Override
-    public JsonToken peek() throws IOException {
-        if (nextToken != null) return nextToken;
-
-        nextToken = jsonParser.nextToken();
-        return nextToken;
-    }
-
-    @Override
-    public JsonParser getJsonParser() {
-        return jsonParser;
-    }
-
-    @Override
-    public Map<String, String> getMetadata() {
-        return metadata;
-    }
-
-    @Override
-    public void setCurrentHeader(String currentHeader) {
-        this.currentHeader = currentHeader;
-    }
-
-    @Override
-    public <T> Unmarshaller<T, JsonUnmarshallerContext> getUnmarshaller(Class<T> type) {
-        return (Unmarshaller<T, JsonUnmarshallerContext>) unmarshallerMap.get(type);
-    }
-
-    @Override
-    public <T> Unmarshaller<T, JsonUnmarshallerContext> getUnmarshaller(Class<T> type, UnmarshallerType unmarshallerType) {
-        return (Unmarshaller<T, JsonUnmarshallerContext>) customUnmarshallerMap.get(unmarshallerType);
-    }
-
-    @Override
-    public JsonToken getCurrentToken() {
-        return currentToken;
-    }
-
-    private void updateContext() throws IOException {
-        lastParsedParentElement = null;
-        if (currentToken == null) return;
-
-        if (currentToken == START_OBJECT || currentToken == START_ARRAY) {
-            if (currentField != null) {
-                stack.push(new JsonFieldTokenPair(currentField, currentToken));
-                currentField = null;
-            }
-        } else if (currentToken == END_OBJECT || currentToken == END_ARRAY) {
-            if (!stack.isEmpty()) {
-                boolean squareBracketsMatch = currentToken == END_ARRAY && stack.peek().getToken() == START_ARRAY;
-                boolean curlyBracketsMatch = currentToken == END_OBJECT && stack.peek().getToken() == START_OBJECT;
-                if (squareBracketsMatch || curlyBracketsMatch) {
-                    lastParsedParentElement = stack.pop().getField();
-                }
-            }
-            currentField = null;
-        } else if (currentToken == FIELD_NAME) {
-            String t = jsonParser.getText();
-            currentField = t;
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder stackString = new StringBuilder();
-
-        for (JsonFieldTokenPair jsonFieldTokenPair : stack) {
-            stackString.append("/")
-                       .append(jsonFieldTokenPair.getField());
-        }
-
-        if (currentField != null) {
-            stackString.append("/")
-                       .append(currentField);
-        }
-
-        return stackString.length() == 0 ? "/" : stackString.toString();
-    }
-
-    @Override
-    public String getLastParsedParentElement() {
-        return lastParsedParentElement;
-    }
-
-    /**
-     * An immutable class used to indicate a JSON field value followed by a
-     * subsequent JSON token. This inner class should only be used by the
-     * private stack to indicate the current state of the context.
-     */
-    private static class JsonFieldTokenPair {
-        private final String field;
-        private final JsonToken jsonToken;
-
-        /**
-         * @param fieldString
-         *            Not null.
-         * @param token
-         *            Not null.
-         */
-        public JsonFieldTokenPair(String fieldString, JsonToken token) {
-            field = fieldString;
-            jsonToken = token;
-        }
-
-        public String getField() {
-            return field;
-        }
-
-        public JsonToken getToken() {
-            return jsonToken;
-        }
-
-        public String toString() {
-            return field + ": " + jsonToken.asString();
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/JsonUnmarshallerContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/JsonUnmarshallerContext.java
--- ./src/main/java/com/amazonaws/transform/JsonUnmarshallerContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/JsonUnmarshallerContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,231 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-
-import com.amazonaws.http.HttpResponse;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-
-/**
- * Used effectively as the API to access the context of performing the
- * json-related unmarshalling.
- * <p>
- * For full support, see {@link JsonUnmarshallerContextImpl}
- * </p>
- */
-public abstract class JsonUnmarshallerContext {
-
-    public enum UnmarshallerType {
-        /**
-         * @see SimpleTypeJsonUnmarshallers.JsonValueStringUnmarshaller
-         */
-        JSON_VALUE
-    }
-
-    /**
-     * Returns the value of the header with the specified name from the
-     * response, or null if not present.
-     *
-     * @param header
-     *            The name of the header to lookup.
-     *
-     * @return The value of the header with the specified name from the
-     *         response. Returns null by default or if the header is not
-     *         present.
-     */
-    public String getHeader(String header) {
-        return null;
-    }
-
-    /**
-     * Returns the original HttpResponse constructed for this request. Returns
-     * null by default.
-     */
-    public HttpResponse getHttpResponse() {
-        return null;
-    }
-
-    /**
-     * Returns the element depth of the parser's current position in the JSON
-     * document being parsed.
-     *
-     * @return The element depth of the parser's current position in the JSON
-     *         document being parsed. Returns -1 by default.
-     */
-    public int getCurrentDepth() {
-        return -1;
-    }
-
-    /**
-     * Returns the text of the current token, or throws an exception if the
-     * current token does not contain text (ex: '{', '}', etc.).
-     *
-     * @return The text of the current token. Returns null by default.
-     *
-     * @throws IOException
-     */
-    public String readText() throws IOException {
-        return null;
-    }
-
-    /**
-     * Returns true if parsing of the Json document is yet to start. Returns
-     * false by default or if the parsing of Json document is not yet started.
-     */
-    public boolean isStartOfDocument() {
-        return false;
-    }
-
-    /**
-     * Tests the specified expression (a JSON field name) against the current
-     * position in the JSON document being parsed.
-     *
-     * @param expression
-     *            The field name to test.
-     * @return True if the expression matches the current document position,
-     *         Returns false by default and in all other cases.
-     */
-    public boolean testExpression(String expression) {
-        return false;
-    }
-
-    /**
-     * Returns the name of the JSON field that is the nearest parent of the
-     * current context.Returns null by default.
-     */
-    public String getCurrentParentElement() {
-        return null;
-    }
-
-    /**
-     * Tests the specified expression (a JSON field name) against the current
-     * position in the JSON document being parsed, and restricts the expression
-     * to matching at the specified stack depth.
-     *
-     * @param expression
-     *            The field name to test.
-     * @param stackDepth
-     *            The depth in the stack representing where the expression must
-     *            start matching in order for this method to return true.
-     *
-     * @return True if the specified expression matches the current position in
-     *         the JSON document, starting from the specified depth. Returns
-     *         false by default.
-     */
-    public boolean testExpression(String expression, int stackDepth) {
-        return false;
-    }
-
-    /**
-     * Returns the next JsonToken from the JsonParser. Returns null by default.
-     */
-    public JsonToken nextToken() throws IOException {
-        return null;
-    }
-
-    /**
-     * Returns the JsonToken which is to be parsed next. Returns null by
-     * default.
-     */
-    public JsonToken peek() throws IOException {
-        return null;
-    }
-
-    /**
-     * Returns the JsonParser used for parsing the Json document. Returns null
-     * by default.
-     */
-    public JsonParser getJsonParser() {
-        return null;
-    }
-
-    /**
-     * Returns any metadata collected through metadata expressions while this
-     * context was reading the JSON events from the JSON document.
-     *
-     * @return A map of any metadata collected through metadata expressions
-     *         while this context was reading the JSON document. Returns an
-     *         empty map by default.
-     */
-    public Map<String, String> getMetadata() {
-        return Collections.emptyMap();
-    }
-
-    /**
-     * Registers an expression, which if matched, will cause the data for the
-     * matching element to be stored in the metadata map under the specified
-     * key.
-     *
-     * @param expression
-     *            The expression an element must match in order for it's data to
-     *            be pulled out and stored in the metadata map.
-     * @param targetDepth
-     *            The depth in the JSON document where the expression match must
-     *            start.
-     * @param storageKey
-     *            The key under which to store the matching element's data.
-     */
-    public void registerMetadataExpression(String expression, int targetDepth,
-            String storageKey) {
-    }
-
-    /**
-     * Sets the name of the response header that is to be read next.
-     */
-    public void setCurrentHeader(String currentHeader) {
-    }
-
-    /**
-     * Returns the current JsonToken that is to be parsed by the parser. Returns
-     * null by default.
-     */
-    public JsonToken getCurrentToken() {
-        return null;
-    }
-
-    /**
-     * This will return the deleted string in stackString when doing update on
-     * the stack. Returns null by default.
-     */
-    public String getLastParsedParentElement() {
-        return null;
-    }
-
-    /**
-     * Returns true if the <code>JsonUnmarshallerContext</code> is involved in
-     * parsing response headers. Else returns false. Returns true by default.
-     */
-    public boolean isInsideResponseHeader() {
-        return true;
-    }
-
-    /**
-     * Returns the JsonUnmarshaller for the specified scalar type. Returns null by default.
-     */
-    public <T> Unmarshaller<T, JsonUnmarshallerContext> getUnmarshaller(Class<T> type) {
-        return null;
-    }
-
-    /**
-     * Returns the JsonUnmarshaller for requested custom unmarshaller type. Returns null by default.
-     */
-    public <T> Unmarshaller<T, JsonUnmarshallerContext> getUnmarshaller(Class<T> type, UnmarshallerType unmarshallerType) {
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/LegacyErrorUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/LegacyErrorUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/LegacyErrorUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/LegacyErrorUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,120 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import static com.amazonaws.util.XpathUtils.asString;
-import static com.amazonaws.util.XpathUtils.xpath;
-
-import java.lang.reflect.Constructor;
-
-import javax.xml.xpath.XPath;
-
-import org.w3c.dom.Node;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonServiceException.ErrorType;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Unmarshalls an AWS error response into an AmazonServiceException, or
- * optionally, a subclass of AmazonServiceException if this class is extended.
- */
-@SdkProtectedApi
-public class LegacyErrorUnmarshaller implements Unmarshaller<AmazonServiceException, Node> {
-    /**
-     * The type of AmazonServiceException that will be instantiated. Subclasses
-     * specialized for a specific type of exception can control this through the
-     * protected constructor.
-     */
-    private final Class<? extends AmazonServiceException> exceptionClass;
-
-    /**
-     * Constructs a new unmarshaller that will unmarshall AWS error responses as
-     * a generic AmazonServiceException object.
-     */
-    public LegacyErrorUnmarshaller() {
-        this(AmazonServiceException.class);
-    }
-
-    /**
-     * Constructor allowing subclasses to specify a specific type of
-     * AmazonServiceException to instantiating when populating the exception
-     * object with data from the AWS error response.
-     *
-     * @param exceptionClass
-     *            The class of AmazonServiceException to create and populate
-     *            when unmarshalling the AWS error response.
-     */
-    public LegacyErrorUnmarshaller(Class<? extends AmazonServiceException> exceptionClass) {
-        this.exceptionClass = exceptionClass;
-    }
-
-    @Override
-    public AmazonServiceException unmarshall(Node in) throws Exception {
-        XPath xpath = xpath();
-        String errorCode = parseErrorCode(in, xpath);
-        String message = asString("Response/Errors/Error/Message", in, xpath);
-        String requestId = asString("Response/RequestID", in, xpath);
-        String errorType = asString("Response/Errors/Error/Type", in, xpath);
-
-        Constructor<? extends AmazonServiceException> constructor = exceptionClass.getConstructor(String.class);
-        AmazonServiceException ase = constructor.newInstance(message);
-        ase.setErrorCode(errorCode);
-        ase.setRequestId(requestId);
-
-        if (errorType == null) {
-            ase.setErrorType(ErrorType.Unknown);
-        } else if (errorType.equalsIgnoreCase("server")) {
-            ase.setErrorType(ErrorType.Service);
-        } else if (errorType.equalsIgnoreCase("client")) {
-            ase.setErrorType(ErrorType.Client);
-        }
-
-        return ase;
-    }
-
-    /**
-     * Returns the AWS error code for the specified error response.
-     *
-     * @param in
-     *            The DOM tree node containing the error response.
-     *
-     * @return The AWS error code contained in the specified error response.
-     *
-     * @throws Exception
-     *             If any problems were encountered pulling out the AWS error
-     *             code.
-     */
-    public String parseErrorCode(Node in) throws Exception {
-        return asString("Response/Errors/Error/Code", in);
-    }
-
-    public String parseErrorCode(Node in, XPath xpath) throws Exception {
-        return asString("Response/Errors/Error/Code", in, xpath);
-    }
-
-    /**
-     * Returns the path to the specified property within an error response.
-     *
-     * @param property
-     *            The name of the desired property.
-     *
-     * @return The path to the specified property within an error message.
-     */
-    public String getErrorPropertyPath(String property) {
-        return "Response/Errors/Error/" + property;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/ListUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/ListUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/ListUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/ListUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,96 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import com.fasterxml.jackson.core.JsonToken;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
-
-/**
- * This unmarshaller assumes that the start array token as already been consumed before getting
- * control of the context.
- */
-public class ListUnmarshaller<T> implements
-        Unmarshaller<List<T>, JsonUnmarshallerContext> {
-
-    private final Unmarshaller<T, JsonUnmarshallerContext> itemUnmarshaller;
-
-    public ListUnmarshaller(
-            Unmarshaller<T, JsonUnmarshallerContext> itemUnmarshaller) {
-        this.itemUnmarshaller = itemUnmarshaller;
-    }
-
-    /**
-     * Unmarshalls the response headers or the json doc in the payload to the
-     * list
-     */
-    public List<T> unmarshall(JsonUnmarshallerContext context) throws Exception {
-        if (context.isInsideResponseHeader()) {
-            return unmarshallResponseHeaderToList(context);
-        }
-        return unmarshallJsonToList(context);
-    }
-
-    /**
-     * Un marshalls the response header into the list.
-     */
-    private List<T> unmarshallResponseHeaderToList(
-            JsonUnmarshallerContext context) throws Exception {
-
-        String headerValue = context.readText();
-
-        List<T> list = new ArrayList<T>();
-
-        String[] headerValues = headerValue.split("[,]");
-
-        for (final String headerVal : headerValues) {
-            list.add(itemUnmarshaller.unmarshall(new JsonUnmarshallerContext() {
-                @Override
-                public String readText() {
-                    return headerVal;
-                }
-            }));
-        }
-        return list;
-    }
-
-    /**
-     * Unmarshalls the current token in the Json document to list.
-     */
-    private List<T> unmarshallJsonToList(JsonUnmarshallerContext context)
-            throws Exception {
-        List<T> list = new ArrayList<T>();
-
-        if (context.getCurrentToken() == JsonToken.VALUE_NULL) {
-            return null;
-        }
-
-        while (true) {
-            JsonToken token = context.nextToken();
-            if (token == null) {
-                return list;
-            }
-
-            if (token == END_ARRAY) {
-                return list;
-            } else {
-                list.add(itemUnmarshaller.unmarshall(context));
-            }
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/MapEntry.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/MapEntry.java
--- ./src/main/java/com/amazonaws/transform/MapEntry.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/MapEntry.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,58 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import java.util.Map;
-
-/**
- * Simple implementation of the Map.Entry interface.
- *
- * @param <K>
- *            The type of the key held in this map entry.
- * @param <V>
- *            The type of the value held in this map entry.
- */
-public class MapEntry<K, V> implements Map.Entry<K, V> {
-    private K key;
-    private V value;
-
-    /* (non-Javadoc)
-     * @see java.util.Map.Entry#getKey()
-     */
-    public K getKey() {
-        return key;
-    }
-
-    /* (non-Javadoc)
-     * @see java.util.Map.Entry#getValue()
-     */
-    public V getValue() {
-        return value;
-    }
-
-    /* (non-Javadoc)
-     * @see java.util.Map.Entry#setValue(java.lang.Object)
-     */
-    public V setValue(V value) {
-        this.value = value;
-        return this.value;
-    }
-
-    public K setKey(K key) {
-        this.key = key;
-        return this.key;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/MapUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/MapUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/MapUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/MapUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
-import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
-import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonToken;
-
-
-public class MapUnmarshaller<K, V> implements Unmarshaller<Map<K, V>, JsonUnmarshallerContext> {
-
-    private final Unmarshaller<K, JsonUnmarshallerContext> keyUnmarshaller;
-    private final Unmarshaller<V, JsonUnmarshallerContext> valueUnmarshaller;
-
-    public MapUnmarshaller(Unmarshaller<K, JsonUnmarshallerContext> keyUnmarshaller, Unmarshaller<V, JsonUnmarshallerContext> valueUnmarshaller) {
-        this.keyUnmarshaller = keyUnmarshaller;
-        this.valueUnmarshaller = valueUnmarshaller;
-    }
-
-    public Map<K, V> unmarshall(JsonUnmarshallerContext context) throws Exception {
-        Map<K, V> map = new HashMap<K, V>();
-        int originalDepth = context.getCurrentDepth();
-
-        if (context.getCurrentToken() == JsonToken.VALUE_NULL) {
-            return null;
-        }
-
-        while (true) {
-            JsonToken token = context.nextToken();
-            if (token == null) return map;
-
-            if (token == FIELD_NAME) {
-                K k = keyUnmarshaller.unmarshall(context);
-                token = context.nextToken();
-                V v = valueUnmarshaller.unmarshall(context);
-                map.put(k, v);
-            } else if (token == END_ARRAY || token == END_OBJECT) {
-                if (context.getCurrentDepth() <= originalDepth) return map;
-            }
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/Marshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/Marshaller.java
--- ./src/main/java/com/amazonaws/transform/Marshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/Marshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,22 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-
-public interface Marshaller<T, R> {
-
-    T marshall(R in);
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/PathMarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/PathMarshallers.java
--- ./src/main/java/com/amazonaws/transform/PathMarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/PathMarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,140 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import com.amazonaws.util.IdempotentUtils;
-import com.amazonaws.util.SdkHttpUtils;
-import com.amazonaws.util.StringUtils;
-
-import static com.amazonaws.util.ValidationUtils.assertNotNull;
-import static com.amazonaws.util.ValidationUtils.assertStringNotEmpty;
-
-public class PathMarshallers {
-
-    /**
-     * Marshaller for non greedy path labels. Value is URL encoded and then replaced in the request URI.
-     */
-    public static final PathMarshaller NON_GREEDY = new NonGreedyPathMarshaller();
-
-    /**
-     * Marshaller for greedy path labels. Value is not URL encoded and replaced in the request URI.
-     */
-    public static final PathMarshaller GREEDY = new GreedyPathMarshaller();
-
-    /**
-     * Marshaller for members marked with the idempotency trait. If the path value is null, a value will
-     * be auto generated by the SDK.
-     */
-    public static final PathMarshaller IDEMPOTENCY = new IdempotencyPathMarshaller();
-
-    /**
-     * Interface for marshalling to a path parameter.
-     */
-    public interface PathMarshaller {
-
-        /**
-         * @param resourcePath Current resource path with path param placeholder
-         * @param paramName    Name of parameter (i.e. placeholder value {Foo})
-         * @param pathValue    String value of path parameter.
-         * @return New URI with placeholder replaced with marshalled value.
-         */
-        String marshall(String resourcePath, String paramName, String pathValue);
-
-        /**
-         * @param resourcePath Current resource path with path param placeholder
-         * @param paramName    Name of parameter (i.e. placeholder value {Foo})
-         * @param pathValue    Integer value of path parameter.
-         * @return New URI with placeholder replaced with marshalled value.
-         */
-        String marshall(String resourcePath, String paramName, Integer pathValue);
-
-        /**
-         * @param resourcePath Current resource path with path param placeholder
-         * @param paramName    Name of parameter (i.e. placeholder value {Foo})
-         * @param pathValue    Long value of path parameter.
-         * @return New URI with placeholder replaced with marshalled value.
-         */
-        String marshall(String resourcePath, String paramName, Long pathValue);
-    }
-
-    private static class NonGreedyPathMarshaller implements PathMarshaller {
-        @Override
-        public String marshall(String resourcePath, String paramName, String pathValue) {
-            assertStringNotEmpty(pathValue, paramName);
-            return resourcePath.replace(String.format("{%s}", paramName), SdkHttpUtils.urlEncode(pathValue, false));
-        }
-
-        @Override
-        public String marshall(String resourcePath, String paramName, Integer pathValue) {
-            assertNotNull(pathValue, paramName);
-            return marshall(resourcePath, paramName, StringUtils.fromInteger(pathValue));
-        }
-
-        @Override
-        public String marshall(String resourcePath, String paramName, Long pathValue) {
-            assertNotNull(pathValue, paramName);
-            return marshall(resourcePath, paramName, StringUtils.fromLong(pathValue));
-        }
-    }
-
-    private static class GreedyPathMarshaller implements PathMarshaller {
-
-        @Override
-        public String marshall(String resourcePath, String paramName, String pathValue) {
-            assertStringNotEmpty(pathValue, paramName);
-            return resourcePath.replace(String.format("{%s+}", paramName), trimLeadingSlash(pathValue));
-        }
-
-        @Override
-        public String marshall(String resourcePath, String paramName, Integer pathValue) {
-            assertNotNull(pathValue, paramName);
-            return marshall(resourcePath, paramName, StringUtils.fromInteger(pathValue));
-        }
-
-        @Override
-        public String marshall(String resourcePath, String paramName, Long pathValue) {
-            assertNotNull(pathValue, paramName);
-            return marshall(resourcePath, paramName, StringUtils.fromLong(pathValue));
-        }
-    }
-
-    private static class IdempotencyPathMarshaller implements PathMarshaller {
-        @Override
-        public String marshall(String resourcePath, String paramName, String pathValue) {
-            if (pathValue != null && pathValue.isEmpty()) {
-                throw new IllegalArgumentException(paramName + " must not be empty. If not set a value will be auto generated");
-            }
-            return resourcePath.replace(String.format("{%s}", paramName),
-                                        SdkHttpUtils.urlEncode(IdempotentUtils.resolveString(pathValue), false));
-        }
-
-        @Override
-        public String marshall(String resourcePath, String paramName, Integer pathValue) {
-            throw new UnsupportedOperationException("Integer idempotency tokens not yet supported");
-        }
-
-        @Override
-        public String marshall(String resourcePath, String paramName, Long pathValue) {
-            throw new UnsupportedOperationException("Long idempotency tokens not yet supported");
-        }
-    }
-
-    private static String trimLeadingSlash(String value) {
-        if (value.startsWith("/")) {
-            return value.replaceFirst("/", "");
-        }
-        return value;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/SimpleTypeCborUnmarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeCborUnmarshallers.java
--- ./src/main/java/com/amazonaws/transform/SimpleTypeCborUnmarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeCborUnmarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,223 +0,0 @@
-/*
- * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-
-@SdkProtectedApi
-public class SimpleTypeCborUnmarshallers {
-    /**
-     * Unmarshaller for String values.
-     */
-    public static class StringCborUnmarshaller implements Unmarshaller<String, JsonUnmarshallerContext> {
-        public String unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.readText();
-        }
-
-        private static final StringCborUnmarshaller instance = new StringCborUnmarshaller();
-
-        public static StringCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Double values.
-     */
-    public static class DoubleCborUnmarshaller implements Unmarshaller<Double, JsonUnmarshallerContext> {
-        public Double unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getDoubleValue();
-        }
-
-        private static final DoubleCborUnmarshaller instance = new DoubleCborUnmarshaller();
-
-        public static DoubleCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Integer values.
-     */
-    public static class IntegerCborUnmarshaller implements Unmarshaller<Integer, JsonUnmarshallerContext> {
-        public Integer unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getIntValue();
-        }
-
-        private static final IntegerCborUnmarshaller instance = new IntegerCborUnmarshaller();
-
-        public static IntegerCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigIntegerCborUnmarshaller implements Unmarshaller<BigInteger, JsonUnmarshallerContext> {
-        public BigInteger unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            JsonParser parser = unmarshallerContext.getJsonParser();
-            JsonToken current = parser.getCurrentToken();
-            if (current == JsonToken.VALUE_NUMBER_INT) {
-                return parser.getBigIntegerValue();
-            } else if (current == JsonToken.VALUE_EMBEDDED_OBJECT) {
-                Object embedded = parser.getEmbeddedObject();
-                return new BigInteger((byte[]) embedded);
-            } else {
-                throw new SdkClientException("Invalid BigInteger Format.");
-            }
-        }
-
-        private static final BigIntegerCborUnmarshaller instance = new BigIntegerCborUnmarshaller();
-
-        public static BigIntegerCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigDecimalCborUnmarshaller implements Unmarshaller<BigDecimal, JsonUnmarshallerContext> {
-        public BigDecimal unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            JsonParser parser = unmarshallerContext.getJsonParser();
-            Unmarshaller<BigInteger, JsonUnmarshallerContext> bigIntegerUnmarshaller = unmarshallerContext.getUnmarshaller(BigInteger.class);
-
-            JsonToken current = parser.getCurrentToken();
-            if (current != JsonToken.START_ARRAY) {
-                throw new SdkClientException("Invalid BigDecimal Format.");
-            }
-            parser.nextToken();
-            int exponent = parser.getIntValue();
-            parser.nextToken();
-            BigInteger mantissa = bigIntegerUnmarshaller.unmarshall(unmarshallerContext);
-            return new BigDecimal(mantissa, exponent);
-        }
-
-        private static final BigDecimalCborUnmarshaller instance = new BigDecimalCborUnmarshaller();
-
-        public static BigDecimalCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Boolean values.
-     */
-    public static class BooleanCborUnmarshaller implements Unmarshaller<Boolean, JsonUnmarshallerContext> {
-        public Boolean unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getBooleanValue();
-        }
-
-        private static final BooleanCborUnmarshaller instance = new BooleanCborUnmarshaller();
-
-        public static BooleanCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Float values.
-     */
-    public static class FloatCborUnmarshaller implements Unmarshaller<Float, JsonUnmarshallerContext> {
-        public Float unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getFloatValue();
-        }
-
-        private static final FloatCborUnmarshaller instance = new FloatCborUnmarshaller();
-
-        public static FloatCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Long values.
-     */
-    public static class LongCborUnmarshaller implements Unmarshaller<Long, JsonUnmarshallerContext> {
-        public Long unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getLongValue();
-        }
-
-        private static final LongCborUnmarshaller instance = new LongCborUnmarshaller();
-
-        public static LongCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Byte values.
-     */
-    public static class ByteCborUnmarshaller implements Unmarshaller<Byte, JsonUnmarshallerContext> {
-        public Byte unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getByteValue();
-        }
-
-        private static final ByteCborUnmarshaller instance = new ByteCborUnmarshaller();
-
-        public static ByteCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Date values - JSON dates come in as epoch seconds.
-     */
-    public static class DateCborUnmarshaller implements Unmarshaller<Date, JsonUnmarshallerContext> {
-        public Date unmarshall(JsonUnmarshallerContext unmarshallerContext)
-                throws Exception {
-            return new Date(unmarshallerContext.getJsonParser().getLongValue());
-        }
-
-        private static final DateCborUnmarshaller instance = new DateCborUnmarshaller();
-
-        public static DateCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for ByteBuffer values.
-     */
-    public static class ByteBufferCborUnmarshaller implements Unmarshaller<ByteBuffer, JsonUnmarshallerContext> {
-        public ByteBuffer unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return ByteBuffer.wrap(unmarshallerContext.getJsonParser().getBinaryValue());
-
-        }
-
-        private static final ByteBufferCborUnmarshaller instance = new ByteBufferCborUnmarshaller();
-
-        public static ByteBufferCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Short values.
-     */
-    public static class ShortCborUnmarshaller implements Unmarshaller<Short, JsonUnmarshallerContext> {
-        public Short unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.getJsonParser().getShortValue();
-        }
-
-        private static final ShortCborUnmarshaller instance = new ShortCborUnmarshaller();
-
-        public static ShortCborUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/transform/SimpleTypeIonUnmarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeIonUnmarshallers.java
--- ./src/main/java/com/amazonaws/transform/SimpleTypeIonUnmarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeIonUnmarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,179 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not
- * use this file except in compliance with the License. A copy of the License is
- * located at
- * 
- * http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed on
- * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-public class SimpleTypeIonUnmarshallers {
-    public static class StringIonUnmarshaller implements Unmarshaller<String, JsonUnmarshallerContext> {
-        @Override
-        public String unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.readText();
-        }
-
-        private static final StringIonUnmarshaller instance = new StringIonUnmarshaller();
-
-        public static StringIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-
-    public static class DoubleIonUnmarshaller implements Unmarshaller<Double, JsonUnmarshallerContext> {
-        @Override
-        public Double unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getDoubleValue();
-        }
-
-        private static final DoubleIonUnmarshaller instance = new DoubleIonUnmarshaller();
-
-        public static DoubleIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class IntegerIonUnmarshaller implements Unmarshaller<Integer, JsonUnmarshallerContext> {
-        @Override
-        public Integer unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getIntValue();
-        }
-
-        private static final IntegerIonUnmarshaller instance = new IntegerIonUnmarshaller();
-
-        public static IntegerIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigIntegerIonUnmarshaller implements Unmarshaller<BigInteger, JsonUnmarshallerContext> {
-        @Override
-        public BigInteger unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getBigIntegerValue();
-        }
-
-        private static final BigIntegerIonUnmarshaller instance = new BigIntegerIonUnmarshaller();
-
-        public static BigIntegerIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigDecimalIonUnmarshaller implements Unmarshaller<BigDecimal, JsonUnmarshallerContext> {
-        @Override
-        public BigDecimal unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getDecimalValue();
-        }
-
-        private static final BigDecimalIonUnmarshaller instance = new BigDecimalIonUnmarshaller();
-
-        public static BigDecimalIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BooleanIonUnmarshaller implements Unmarshaller<Boolean, JsonUnmarshallerContext> {
-        @Override
-        public Boolean unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getBooleanValue();
-        }
-
-        private static final BooleanIonUnmarshaller instance = new BooleanIonUnmarshaller();
-
-        public static BooleanIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class FloatIonUnmarshaller implements Unmarshaller<Float, JsonUnmarshallerContext> {
-        @Override
-        public Float unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getFloatValue();
-        }
-
-        private static final FloatIonUnmarshaller instance = new FloatIonUnmarshaller();
-
-        public static FloatIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class LongIonUnmarshaller implements Unmarshaller<Long, JsonUnmarshallerContext> {
-        @Override
-        public Long unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getLongValue();
-        }
-
-        private static final LongIonUnmarshaller instance = new LongIonUnmarshaller();
-
-        public static LongIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class ByteIonUnmarshaller implements Unmarshaller<Byte, JsonUnmarshallerContext> {
-        @Override
-        public Byte unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getByteValue();
-        }
-
-        private static final ByteIonUnmarshaller instance = new ByteIonUnmarshaller();
-
-        public static ByteIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class DateIonUnmarshaller implements Unmarshaller<Date, JsonUnmarshallerContext> {
-        @Override
-        public Date unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return (Date) context.getJsonParser().getEmbeddedObject();
-        }
-
-        private static final DateIonUnmarshaller instance = new DateIonUnmarshaller();
-
-        public static DateIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class ByteBufferIonUnmarshaller implements Unmarshaller<ByteBuffer, JsonUnmarshallerContext> {
-        @Override
-        public ByteBuffer unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return (ByteBuffer) context.getJsonParser().getEmbeddedObject();
-        }
-
-        private static final ByteBufferIonUnmarshaller instance = new ByteBufferIonUnmarshaller();
-
-        public static ByteBufferIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class ShortIonUnmarshaller implements Unmarshaller<Short, JsonUnmarshallerContext> {
-        @Override
-        public Short unmarshall(JsonUnmarshallerContext context) throws Exception {
-            return context.getJsonParser().getShortValue();
-        }
-
-        private static final ShortIonUnmarshaller instance = new ShortIonUnmarshaller();
-
-        public static ShortIonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/SimpleTypeJsonUnmarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeJsonUnmarshallers.java
--- ./src/main/java/com/amazonaws/transform/SimpleTypeJsonUnmarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeJsonUnmarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,264 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.util.Base64;
-import com.amazonaws.util.DateUtils;
-import com.fasterxml.jackson.core.JsonToken;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.Date;
-
-public class SimpleTypeJsonUnmarshallers {
-    /**
-     * Unmarshaller for String values.
-     */
-    public static class StringJsonUnmarshaller implements Unmarshaller<String, JsonUnmarshallerContext> {
-        public String unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.readText();
-        }
-
-        private static final StringJsonUnmarshaller instance = new StringJsonUnmarshaller();
-
-        public static StringJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for fields with JSON values. For headers, JSON values are base-64 encoded and are decoded here. For payloads,
-     * JSON values are treated like normal strings.
-     */
-    public static class JsonValueStringUnmarshaller extends StringJsonUnmarshaller {
-        public String unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String stringValue = super.unmarshall(unmarshallerContext);
-            return !unmarshallerContext.isInsideResponseHeader()
-                   ? stringValue
-                   : new String(Base64.decode(stringValue), Charset.forName("utf-8"));
-        }
-
-        private static final JsonValueStringUnmarshaller INSTANCE = new JsonValueStringUnmarshaller();
-        public static JsonValueStringUnmarshaller getInstance() {
-            return INSTANCE;
-        }
-    }
-
-    /**
-     * Unmarshaller for Double values.
-     */
-    public static class DoubleJsonUnmarshaller implements Unmarshaller<Double, JsonUnmarshallerContext> {
-        public Double unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String doubleString = unmarshallerContext.readText();
-            return (doubleString == null) ? null : Double.parseDouble(doubleString);
-        }
-
-        private static final DoubleJsonUnmarshaller instance = new DoubleJsonUnmarshaller();
-
-        public static DoubleJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Integer values.
-     */
-    public static class IntegerJsonUnmarshaller implements Unmarshaller<Integer, JsonUnmarshallerContext> {
-        public Integer unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String intString = unmarshallerContext.readText();
-            return (intString == null) ? null : Integer.parseInt(intString);
-        }
-
-        private static final IntegerJsonUnmarshaller instance = new IntegerJsonUnmarshaller();
-
-        public static IntegerJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigIntegerJsonUnmarshaller implements Unmarshaller<BigInteger, JsonUnmarshallerContext> {
-        public BigInteger unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String intString = unmarshallerContext.readText();
-            return (intString == null) ? null : new BigInteger(intString);
-        }
-
-        private static final BigIntegerJsonUnmarshaller instance = new BigIntegerJsonUnmarshaller();
-
-        public static BigIntegerJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigDecimalJsonUnmarshaller implements Unmarshaller<BigDecimal, JsonUnmarshallerContext> {
-        public BigDecimal unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String s = unmarshallerContext.readText();
-            return (s == null) ? null : new BigDecimal(s);
-        }
-
-        private static final BigDecimalJsonUnmarshaller instance = new BigDecimalJsonUnmarshaller();
-
-        public static BigDecimalJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Boolean values.
-     */
-    public static class BooleanJsonUnmarshaller implements Unmarshaller<Boolean, JsonUnmarshallerContext> {
-        public Boolean unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String booleanString = unmarshallerContext.readText();
-            return (booleanString == null) ? null : Boolean.parseBoolean(booleanString);
-        }
-
-        private static final BooleanJsonUnmarshaller instance = new BooleanJsonUnmarshaller();
-
-        public static BooleanJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Float values.
-     */
-    public static class FloatJsonUnmarshaller implements Unmarshaller<Float, JsonUnmarshallerContext> {
-        public Float unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String floatString = unmarshallerContext.readText();
-            return (floatString == null) ? null : Float.valueOf(floatString);
-        }
-
-        private static final FloatJsonUnmarshaller instance = new FloatJsonUnmarshaller();
-
-        public static FloatJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Long values.
-     */
-    public static class LongJsonUnmarshaller implements Unmarshaller<Long, JsonUnmarshallerContext> {
-        public Long unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String longString = unmarshallerContext.readText();
-            return (longString == null) ? null : Long.parseLong(longString);
-        }
-
-        private static final LongJsonUnmarshaller instance = new LongJsonUnmarshaller();
-
-        public static LongJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Byte values.
-     */
-    public static class ByteJsonUnmarshaller implements Unmarshaller<Byte, JsonUnmarshallerContext> {
-        public Byte unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String byteString = unmarshallerContext.readText();
-            return (byteString == null) ? null : Byte.valueOf(byteString);
-        }
-
-        private static final ByteJsonUnmarshaller instance = new ByteJsonUnmarshaller();
-
-        public static ByteJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Date values - JSON dates come in as epoch seconds for AWS services and ISO8601 string
-     * for API Gateway fronted services..
-     */
-    public static class DateJsonUnmarshaller implements Unmarshaller<Date, JsonUnmarshallerContext> {
-        public Date unmarshall(JsonUnmarshallerContext unmarshallerContext)
-                throws Exception {
-            // If value is string, assume ISO8601. Otherwise parse as epoch seconds.
-            if (unmarshallerContext.getCurrentToken() == JsonToken.VALUE_STRING) {
-                return DateUtils.parseISO8601Date(unmarshallerContext.readText());
-            } else {
-                return DateUtils.parseServiceSpecificDate(unmarshallerContext.readText());
-            }
-        }
-
-        private static final DateJsonUnmarshaller instance = new DateJsonUnmarshaller();
-
-        public static DateJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for ByteBuffer values.
-     */
-    public static class ByteBufferJsonUnmarshaller implements Unmarshaller<ByteBuffer, JsonUnmarshallerContext> {
-        public ByteBuffer unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String base64EncodedString = unmarshallerContext.readText();
-            if (base64EncodedString == null) {
-                return null;
-            }
-            byte[] decodedBytes = Base64.decode(base64EncodedString);
-            return ByteBuffer.wrap(decodedBytes);
-
-        }
-
-        private static final ByteBufferJsonUnmarshaller instance = new ByteBufferJsonUnmarshaller();
-
-        public static ByteBufferJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Character values.
-     */
-    public static class CharacterJsonUnmarshaller implements Unmarshaller<Character, JsonUnmarshallerContext> {
-        public Character unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String charString = unmarshallerContext.readText();
-
-            if (charString == null) return null;
-
-            charString = charString.trim();
-            if (charString.isEmpty() || charString.length() > 1)
-                throw new SdkClientException("'" + charString
-                        + "' cannot be converted to Character");
-            return Character.valueOf(charString.charAt(0));
-        }
-
-        private static final CharacterJsonUnmarshaller instance = new CharacterJsonUnmarshaller();
-
-        public static CharacterJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Short values.
-     */
-    public static class ShortJsonUnmarshaller implements Unmarshaller<Short, JsonUnmarshallerContext> {
-        public Short unmarshall(JsonUnmarshallerContext unmarshallerContext) throws Exception {
-            String shortString = unmarshallerContext.readText();
-            return (shortString == null) ? null : Short.valueOf(shortString);
-        }
-
-        private static final ShortJsonUnmarshaller instance = new ShortJsonUnmarshaller();
-
-        public static ShortJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/SimpleTypeStaxUnmarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeStaxUnmarshallers.java
--- ./src/main/java/com/amazonaws/transform/SimpleTypeStaxUnmarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeStaxUnmarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,254 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.util.Base64;
-import com.amazonaws.util.DateUtils;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-/**
- * Collection of StAX unmarshallers for simple data types.
- */
-public class SimpleTypeStaxUnmarshallers {
-    /** Shared logger */
-    private static Log log = LogFactory.getLog(SimpleTypeStaxUnmarshallers.class);
-
-    /**
-     * Unmarshaller for String values.
-     */
-    public static class StringStaxUnmarshaller implements Unmarshaller<String, StaxUnmarshallerContext> {
-        public String unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            return unmarshallerContext.readText();
-        }
-
-        private static final StringStaxUnmarshaller instance = new StringStaxUnmarshaller();
-
-        public static StringStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigDecimalStaxUnmarshaller implements Unmarshaller<BigDecimal, StaxUnmarshallerContext> {
-        public BigDecimal unmarshall(StaxUnmarshallerContext unmarshallerContext)
-                throws Exception {
-            String s = unmarshallerContext.readText();
-            return (s == null) ? null : new BigDecimal(s);
-        }
-
-        private static final BigDecimalStaxUnmarshaller instance = new BigDecimalStaxUnmarshaller();
-
-        public static BigDecimalStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    public static class BigIntegerStaxUnmarshaller implements Unmarshaller<BigInteger, StaxUnmarshallerContext> {
-        public BigInteger unmarshall(StaxUnmarshallerContext unmarshallerContext)
-                throws Exception {
-            String s = unmarshallerContext.readText();
-            return (s == null) ? null : new BigInteger(s);
-        }
-
-        private static final BigIntegerStaxUnmarshaller instance = new BigIntegerStaxUnmarshaller();
-
-        public static BigIntegerStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Double values.
-     */
-    public static class DoubleStaxUnmarshaller implements Unmarshaller<Double, StaxUnmarshallerContext> {
-        public Double unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String doubleString = unmarshallerContext.readText();
-            return (doubleString == null) ? null : Double.parseDouble(doubleString);
-        }
-
-        private static final DoubleStaxUnmarshaller instance = new DoubleStaxUnmarshaller();
-
-        public static DoubleStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Integer values.
-     */
-    public static class IntegerStaxUnmarshaller implements Unmarshaller<Integer, StaxUnmarshallerContext> {
-        public Integer unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String intString = unmarshallerContext.readText();
-            return (intString == null) ? null : Integer.parseInt(intString);
-        }
-
-        private static final IntegerStaxUnmarshaller instance = new IntegerStaxUnmarshaller();
-
-        public static IntegerStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Boolean values.
-     */
-    public static class BooleanStaxUnmarshaller implements Unmarshaller<Boolean, StaxUnmarshallerContext> {
-        public Boolean unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String booleanString = unmarshallerContext.readText();
-            return (booleanString == null) ? null : Boolean.parseBoolean(booleanString);
-        }
-
-        private static final BooleanStaxUnmarshaller instance = new BooleanStaxUnmarshaller();
-
-        public static BooleanStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Float values.
-     */
-    public static class FloatStaxUnmarshaller implements Unmarshaller<Float, StaxUnmarshallerContext> {
-        public Float unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String floatString = unmarshallerContext.readText();
-            return (floatString == null) ? null : Float.valueOf(floatString);
-        }
-
-        private static final FloatStaxUnmarshaller instance = new FloatStaxUnmarshaller();
-
-        public static FloatStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Long values.
-     */
-    public static class LongStaxUnmarshaller implements Unmarshaller<Long, StaxUnmarshallerContext> {
-        public Long unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String longString = unmarshallerContext.readText();
-            return (longString == null) ? null : Long.parseLong(longString);
-        }
-
-        private static final LongStaxUnmarshaller instance = new LongStaxUnmarshaller();
-
-        public static LongStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Byte values.
-     */
-    public static class ByteStaxUnmarshaller implements Unmarshaller<Byte, StaxUnmarshallerContext> {
-        public Byte unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String byteString = unmarshallerContext.readText();
-            return (byteString == null) ? null : Byte.valueOf(byteString);
-        }
-
-        private static final ByteStaxUnmarshaller instance = new ByteStaxUnmarshaller();
-
-        public static ByteStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Date values.
-     */
-    public static class DateStaxUnmarshaller implements Unmarshaller<Date, StaxUnmarshallerContext> {
-        public Date unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String dateString = unmarshallerContext.readText();
-            if (dateString == null) return null;
-
-            try {
-                return DateUtils.parseISO8601Date(dateString);
-            } catch (Exception e) {
-                log.warn("Unable to parse date '" + dateString + "':  " + e.getMessage(), e);
-                return null;
-            }
-        }
-
-        private static final DateStaxUnmarshaller instance = new DateStaxUnmarshaller();
-
-        public static DateStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for ByteBuffer values.
-     */
-    public static class ByteBufferStaxUnmarshaller implements Unmarshaller<ByteBuffer, StaxUnmarshallerContext> {
-        public ByteBuffer unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String base64EncodedString = unmarshallerContext.readText();
-            byte[] decodedBytes = Base64.decode(base64EncodedString);
-            return ByteBuffer.wrap(decodedBytes);
-
-        }
-
-        private static final ByteBufferStaxUnmarshaller instance = new ByteBufferStaxUnmarshaller();
-
-        public static ByteBufferStaxUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Character values.
-     */
-    public static class CharacterJsonUnmarshaller implements Unmarshaller<Character, StaxUnmarshallerContext> {
-        public Character unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String charString = unmarshallerContext.readText();
-
-            if (charString == null) return null;
-
-            charString = charString.trim();
-            if (charString.isEmpty() || charString.length() > 1)
-                throw new SdkClientException("'" + charString
-                        + "' cannot be converted to Character");
-            return Character.valueOf(charString.charAt(0));
-        }
-
-        private static final CharacterJsonUnmarshaller instance = new CharacterJsonUnmarshaller();
-
-        public static CharacterJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-
-    /**
-     * Unmarshaller for Short values.
-     */
-    public static class ShortJsonUnmarshaller implements Unmarshaller<Short, StaxUnmarshallerContext> {
-        public Short unmarshall(StaxUnmarshallerContext unmarshallerContext) throws Exception {
-            String shortString = unmarshallerContext.readText();
-            return (shortString == null) ? null : Short.valueOf(shortString);
-        }
-
-        private static final ShortJsonUnmarshaller instance = new ShortJsonUnmarshaller();
-
-        public static ShortJsonUnmarshaller getInstance() {
-            return instance;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/SimpleTypeUnmarshallers.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeUnmarshallers.java
--- ./src/main/java/com/amazonaws/transform/SimpleTypeUnmarshallers.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/SimpleTypeUnmarshallers.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,164 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-import org.w3c.dom.Node;
-
-import com.amazonaws.util.XpathUtils;
-
-/**
- * Collection of unmarshallers for simple data types.
- */
-public class SimpleTypeUnmarshallers {
-    
-    /**
-     * Unmarshaller for String values.
-     */
-    public static class StringUnmarshaller implements Unmarshaller<String, Node> {
-        public String unmarshall(Node in) throws Exception {
-            return XpathUtils.asString(".", in);
-        }
-
-        private static StringUnmarshaller instance;
-        public static StringUnmarshaller getInstance() {
-            if (instance == null) instance = new StringUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Double values.
-     */
-    public static class DoubleUnmarshaller implements Unmarshaller<Double, Node> {
-        public Double unmarshall(Node in) throws Exception {
-            return XpathUtils.asDouble(".", in);
-        }
-        
-        private static DoubleUnmarshaller instance;
-        public static DoubleUnmarshaller getInstance() {
-            if (instance == null) instance = new DoubleUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Integer values.
-     */
-    public static class IntegerUnmarshaller implements Unmarshaller<Integer, Node> {
-        public Integer unmarshall(Node in) throws Exception {
-            return XpathUtils.asInteger(".", in);
-        }
-
-        private static IntegerUnmarshaller instance;
-        public static IntegerUnmarshaller getInstance() {
-            if (instance == null) instance = new IntegerUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Boolean values.
-     */
-    public static class BooleanUnmarshaller implements Unmarshaller<Boolean, Node> {
-        public Boolean unmarshall(Node in) throws Exception {
-            return XpathUtils.asBoolean(".", in);
-        }
-
-        private static BooleanUnmarshaller instance;
-        public static BooleanUnmarshaller getInstance() {
-            if (instance == null) instance = new BooleanUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Float values.
-     */
-    public static class FloatUnmarshaller implements Unmarshaller<Float, Node> {
-        public Float unmarshall(Node in) throws Exception {
-            return XpathUtils.asFloat(".", in);
-        }
-
-        private static FloatUnmarshaller instance;
-        public static FloatUnmarshaller getInstance() {
-            if (instance == null) instance = new FloatUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Long values.
-     */
-    public static class LongUnmarshaller implements Unmarshaller<Long, Node> {
-        public Long unmarshall(Node in) throws Exception {
-            return XpathUtils.asLong(".", in);
-        }
-
-        private static LongUnmarshaller instance;
-        public static LongUnmarshaller getInstance() {
-            if (instance == null) instance = new LongUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Byte values.
-     */
-    public static class ByteUnmarshaller implements Unmarshaller<Byte, Node> {
-        public Byte unmarshall(Node in) throws Exception {
-            return XpathUtils.asByte(".", in);
-        }
-
-        private static ByteUnmarshaller instance;
-        public static ByteUnmarshaller getInstance() {
-            if (instance == null) instance = new ByteUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for Date values.
-     */
-    public static class DateUnmarshaller implements Unmarshaller<Date, Node> {
-        public Date unmarshall(Node in) throws Exception {
-            return XpathUtils.asDate(".", in);
-        }
-
-        private static DateUnmarshaller instance;
-        public static DateUnmarshaller getInstance() {
-            if (instance == null) instance = new DateUnmarshaller();
-            return instance;
-        }
-    }
-    
-    /**
-     * Unmarshaller for ByteBuffer values.
-     */
-    public static class ByteBufferUnmarshaller implements Unmarshaller<ByteBuffer, Node> {
-        public ByteBuffer unmarshall(Node in) throws Exception {
-            return XpathUtils.asByteBuffer(".", in);
-        }
-
-        private static ByteBufferUnmarshaller instance;
-        public static ByteBufferUnmarshaller getInstance() {
-            if (instance == null) instance = new ByteBufferUnmarshaller();
-            return instance;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/StandardErrorUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/StandardErrorUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/StandardErrorUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/StandardErrorUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,114 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import static com.amazonaws.util.XpathUtils.asString;
-import static com.amazonaws.util.XpathUtils.xpath;
-
-import javax.xml.xpath.XPath;
-
-import org.w3c.dom.Node;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonServiceException.ErrorType;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-/**
- * Error unmarshaller that knows how to interpret a standard AWS error message
- * (i.e. where to find the AWS error code, the error message, etc.) and turn it
- * into an AmazonServiceException.
- *
- * @see LegacyErrorUnmarshaller
- */
-@SdkProtectedApi
-public class StandardErrorUnmarshaller extends AbstractErrorUnmarshaller<Node> {
-
-    /**
-     * Constructs a new unmarshaller that will unmarshall a standard AWS error
-     * message as a generic AmazonServiceException object.
-     */
-    public StandardErrorUnmarshaller() {}
-
-    /**
-     * Constructor allowing subclasses to specify a specific type of
-     * AmazonServiceException to instantiating when populating the exception
-     * object with data from the error message.
-     *
-     * @param exceptionClass
-     *            The class of AmazonServiceException to create and populate
-     *            when unmarshalling the error message.
-     */
-    public StandardErrorUnmarshaller(Class<? extends AmazonServiceException> exceptionClass) {
-        super(exceptionClass);
-    }
-
-    /**
-     * @see com.amazonaws.transform.Unmarshaller#unmarshall(java.lang.Object)
-     */
-    public AmazonServiceException unmarshall(Node in) throws Exception {
-        XPath xpath = xpath();
-        String errorCode = parseErrorCode(in, xpath);
-        String errorType = asString("ErrorResponse/Error/Type", in, xpath);
-        String requestId = asString("ErrorResponse/RequestId", in, xpath);
-        String message = asString("ErrorResponse/Error/Message", in, xpath);
-
-        AmazonServiceException ase = newException(message);
-        ase.setErrorCode(errorCode);
-        ase.setRequestId(requestId);
-
-        if (errorType == null) {
-            ase.setErrorType(ErrorType.Unknown);
-        } else if (errorType.equalsIgnoreCase("Receiver")) {
-            ase.setErrorType(ErrorType.Service);
-        } else if (errorType.equalsIgnoreCase("Sender")) {
-            ase.setErrorType(ErrorType.Client);
-        }
-
-        return ase;
-    }
-
-    /**
-     * Returns the AWS error code for the specified error response.
-     *
-     * @param in
-     *            The DOM tree node containing the error response.
-     *
-     * @return The AWS error code contained in the specified error response.
-     *
-     * @throws Exception
-     *             If any problems were encountered pulling out the AWS error
-     *             code.
-     */
-    public String parseErrorCode(Node in) throws Exception {
-        return asString("ErrorResponse/Error/Code", in);
-    }
-
-    public String parseErrorCode(Node in, XPath xpath) throws Exception {
-        return asString("ErrorResponse/Error/Code", in, xpath);
-    }
-
-    /**
-     * Returns the path to the specified property within an error response.
-     *
-     * @param property
-     *            The name of the desired property.
-     *
-     * @return The path to the specified property within an error message.
-     */
-    public String getErrorPropertyPath(String property) {
-        return "ErrorResponse/Error/" + property;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/StaxUnmarshallerContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/StaxUnmarshallerContext.java
--- ./src/main/java/com/amazonaws/transform/StaxUnmarshallerContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/StaxUnmarshallerContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,305 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.XMLEvent;
-
-/**
- * Contains the unmarshalling state for the parsing of an XML response. The
- * unmarshallers are stateless so that they can be reused, so this class holds
- * the state while different unmarshallers work together to parse an XML
- * response. It also tracks the current position and element depth of the
- * document being parsed and provides utilties for accessing the next XML event
- * from the parser, reading element text, handling attribute XML events, etc.
- */
-public class StaxUnmarshallerContext {
-
-    private XMLEvent currentEvent;
-    private final XMLEventReader eventReader;
-
-    public final Stack<String> stack = new Stack<String>();
-    private String stackString = "";
-
-    private Map<String, String> metadata = new HashMap<String, String>();
-    private List<MetadataExpression> metadataExpressions = new ArrayList<MetadataExpression>();
-
-    private Iterator<?> attributeIterator;
-    private final Map<String, String> headers;
-
-    private String currentHeader;
-
-    public void setCurrentHeader(String currentHeader) {
-        this.currentHeader = currentHeader;
-    }
-
-    public boolean isInsideResponseHeader() {
-        return currentEvent == null;
-    }
-
-    /**
-     * Constructs a new unmarshaller context using the specified source of XML events.
-     *
-     * @param eventReader
-     *            The source of XML events for this unmarshalling context.
-     */
-    public StaxUnmarshallerContext(XMLEventReader eventReader) {
-        this(eventReader, null);
-    }
-
-    /**
-     * Constructs a new unmarshaller context using the specified source of XML
-     * events, and a set of response headers.
-     *
-     * @param eventReader
-     *            The source of XML events for this unmarshalling context.
-     * @param headers
-     *            The set of response headers associated with this unmarshaller
-     *            context.
-     */
-    public StaxUnmarshallerContext(XMLEventReader eventReader, Map<String, String> headers) {
-        this.eventReader = eventReader;
-        this.headers = headers;
-    }
-
-    /**
-     * Returns the value of the header with the specified name from the
-     * response, or null if not present.
-     *
-     * @param header
-     *            The name of the header to lookup.
-     *
-     * @return The value of the header with the specified name from the
-     *         response, or null if not present.
-     */
-    public String getHeader(String header) {
-        if (headers == null) return null;
-
-        return headers.get(header);
-    }
-
-    /**
-     * Returns the text contents of the current element being parsed.
-     *
-     * @return The text contents of the current element being parsed.
-     * @throws XMLStreamException
-     */
-    public String readText() throws XMLStreamException {
-        if (isInsideResponseHeader()) {
-            return getHeader(currentHeader);
-        }
-        if (currentEvent.isAttribute()) {
-            Attribute attribute = (Attribute)currentEvent;
-            return attribute.getValue();
-        }
-
-        StringBuilder sb = new StringBuilder();
-        while (true) {
-            XMLEvent event = eventReader.peek();
-            if (event.getEventType() == XMLStreamConstants.CHARACTERS) {
-                eventReader.nextEvent();
-                sb.append(event.asCharacters().getData());
-            } else if (event.getEventType() == XMLStreamConstants.END_ELEMENT) {
-                return sb.toString();
-            } else {
-                throw new RuntimeException("Encountered unexpected event: " + event.toString());
-            }
-        }
-    }
-
-    /**
-     * Returns the element depth of the parser's current position in the XML
-     * document being parsed.
-     *
-     * @return The element depth of the parser's current position in the XML
-     *         document being parsed.
-     */
-    public int getCurrentDepth() {
-        return stack.size();
-    }
-
-    /**
-     * Tests the specified expression against the current position in the XML
-     * document being parsed.
-     *
-     * @param expression
-     *            The psuedo-xpath expression to test.
-     * @return True if the expression matches the current document position,
-     *         otherwise false.
-     */
-    public boolean testExpression(String expression) {
-        if (expression.equals(".")) return true;
-        return stackString.endsWith(expression);
-    }
-
-    /**
-     * Tests the specified expression against the current position in the XML
-     * document being parsed, and restricts the expression to matching at the
-     * specified stack depth.
-     *
-     * @param expression
-     *            The psuedo-xpath expression to test.
-     * @param startingStackDepth
-     *            The depth in the stack representing where the expression must
-     *            start matching in order for this method to return true.
-     *
-     * @return True if the specified expression matches the current position in
-     *         the XML document, starting from the specified depth.
-     */
-    public boolean testExpression(String expression, int startingStackDepth) {
-        if (expression.equals(".")) return true;
-
-        int index = -1;
-        while ((index = expression.indexOf("/", index + 1)) > -1) {
-            // Don't consider attributes a new depth level
-            if (expression.charAt(index + 1) != '@') {
-                startingStackDepth++;
-            }
-        }
-
-
-        return (startingStackDepth == getCurrentDepth()
-                && stackString.endsWith("/" + expression));
-    }
-
-    /**
-     * Returns true if this unmarshaller context is at the very beginning of a
-     * source document (i.e. no data has been parsed from the document yet).
-     *
-     * @return true if this unmarshaller context is at the very beginning of a
-     *         source document (i.e. no data has been parsed from the document
-     *         yet).
-     */
-    public boolean isStartOfDocument() throws XMLStreamException {
-        return eventReader.peek().isStartDocument();
-    }
-
-    /**
-     * Returns the next XML event for the document being parsed.
-     *
-     * @return The next XML event for the document being parsed.
-     *
-     * @throws XMLStreamException
-     */
-    public XMLEvent nextEvent() throws XMLStreamException {
-        if (attributeIterator != null && attributeIterator.hasNext()) {
-            currentEvent = (XMLEvent)attributeIterator.next();
-        } else {
-            currentEvent = eventReader.nextEvent();
-        }
-
-        if (currentEvent.isStartElement()) {
-            attributeIterator = currentEvent.asStartElement().getAttributes();
-        }
-
-        updateContext(currentEvent);
-
-        if (eventReader.hasNext()) {
-            XMLEvent nextEvent = eventReader.peek();
-            if (nextEvent != null && nextEvent.isCharacters()) {
-                for (MetadataExpression metadataExpression : metadataExpressions) {
-                    if (testExpression(metadataExpression.expression, metadataExpression.targetDepth)) {
-                        metadata.put(metadataExpression.key, nextEvent.asCharacters().getData());
-                    }
-                }
-            }
-        }
-
-        return currentEvent;
-    }
-
-    /**
-     * Returns any metadata collected through metadata expressions while this
-     * context was reading the XML events from the XML document.
-     *
-     * @return A map of any metadata collected through metadata expressions
-     *         while this context was reading the XML document.
-     */
-    public Map<String, String> getMetadata() {
-        return metadata;
-    }
-
-    /**
-     * Registers an expression, which if matched, will cause the data for the
-     * matching element to be stored in the metadata map under the specified
-     * key.
-     *
-     * @param expression
-     *            The expression an element must match in order for it's data to
-     *            be pulled out and stored in the metadata map.
-     * @param targetDepth
-     *            The depth in the XML document where the expression match must
-     *            start.
-     * @param storageKey
-     *            The key under which to store the matching element's data.
-     */
-    public void registerMetadataExpression(String expression, int targetDepth, String storageKey) {
-        metadataExpressions.add(new MetadataExpression(expression, targetDepth, storageKey));
-    }
-
-
-    /*
-     * Private Interface
-     */
-
-    /**
-     * Simple container for the details of a metadata expression this
-     * unmarshaller context is looking for.
-     */
-    private static class MetadataExpression {
-        public String expression;
-        public int targetDepth;
-        public String key;
-
-        public MetadataExpression(String expression, int targetDepth, String key) {
-            this.expression = expression;
-            this.targetDepth = targetDepth;
-            this.key = key;
-        }
-    }
-
-    private void updateContext(XMLEvent event) {
-        if (event == null) return;
-
-        if (event.isEndElement()) {
-            stack.pop();
-            stackString = "";
-            for (String s : stack) {
-                stackString += "/" + s;
-            }
-        } else if (event.isStartElement()) {
-            stack.push(event.asStartElement().getName().getLocalPart());
-            stackString += "/" + event.asStartElement().getName().getLocalPart();
-        } else if (event.isAttribute()) {
-            Attribute attribute = (Attribute)event;
-            stackString = "";
-            for (String s : stack) {
-                stackString += "/" + s;
-            }
-            stackString += "/@" + attribute.getName().getLocalPart();
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/Unmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/Unmarshaller.java
--- ./src/main/java/com/amazonaws/transform/Unmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/Unmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,21 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-public interface Unmarshaller<T, R> {
-
-    public T unmarshall(R in) throws Exception;
-    
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/VoidJsonUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/VoidJsonUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/VoidJsonUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/VoidJsonUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-
-/**
- * Simple unmarshaller that iterates through the JSON events but always
- * returns null.
- */
-public class VoidJsonUnmarshaller<T> implements Unmarshaller<T, JsonUnmarshallerContext> {
-    public T unmarshall(JsonUnmarshallerContext context) throws Exception {
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/VoidStaxUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/VoidStaxUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/VoidStaxUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/VoidStaxUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-/**
- * Simple StAX unmarshaller that iterates through the XML events but always
- * returns null.
- */
-public class VoidStaxUnmarshaller<T> implements Unmarshaller<T, StaxUnmarshallerContext> {
-    public T unmarshall(StaxUnmarshallerContext context) throws Exception {
-        while (context.nextEvent().isEndDocument() == false);
-        return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/transform/VoidUnmarshaller.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/VoidUnmarshaller.java
--- ./src/main/java/com/amazonaws/transform/VoidUnmarshaller.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/transform/VoidUnmarshaller.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.transform;
-
-import org.w3c.dom.Node;
-
-/**
- * Simple Unmarshaller implementation that always returns null.
- */
-public class VoidUnmarshaller implements Unmarshaller<Void, Node> {
-    /**
-     * @see com.amazonaws.transform.Unmarshaller#unmarshall(java.lang.Object)
-     */
-    public Void unmarshall(Node in) throws Exception {
-            return null;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/AbstractBase32Codec.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AbstractBase32Codec.java
--- ./src/main/java/com/amazonaws/util/AbstractBase32Codec.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AbstractBase32Codec.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,280 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-import static com.amazonaws.util.CodecUtils.sanityCheckLastPos;
-
-/**
- * Common base class for Base 32 like codec implementation.
- * 
- * @author Hanson Char
- */
-abstract class AbstractBase32Codec implements Codec {
-    private static final int MASK_2BITS = (1 << 2) - 1;
-    private static final int MASK_3BITS = (1 << 3) - 1;
-    private static final int MASK_4BITS = (1 << 4) - 1;
-    private static final int MASK_5BITS = (1 << 5) - 1;
-    // Base 32 alphabet as defined at http://www.ietf.org/rfc/rfc4648.txt
-    private static final byte PAD = '=';
-    
-    private final byte[] alphabets;
-
-    protected AbstractBase32Codec(byte[] alphabets) {
-        this.alphabets = alphabets;
-    }
-
-    @Override
-    public final byte[] encode(byte[] src) {
-        final int num5bytes = src.length / 5;
-        final int remainder = src.length % 5;
-        
-        if (remainder == 0)
-        {
-            byte[] dest = new byte[num5bytes * 8];
-    
-            for (int s=0,d=0; s < src.length; s+=5, d+=8)
-                encode5bytes(src, s, dest, d);
-            return dest;
-        }
-        
-        byte[] dest = new byte[(num5bytes+1) * 8];
-        int s=0, d=0;
-        
-        for (; s < src.length-remainder; s+=5, d+=8)
-            encode5bytes(src, s, dest, d);
-        
-        switch(remainder) {
-            case 1:
-                encode1byte(src, s, dest, d);
-                break;
-            case 2:
-                encode2bytes(src, s, dest, d);
-                break;
-            case 3:
-                encode3bytes(src, s, dest, d);
-                break;
-            case 4:
-                encode4bytes(src, s, dest, d);
-                break;
-            default:
-                throw new IllegalStateException();
-        }
-        return dest;
-    }
-    
-    private final void encode5bytes(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s++]) >>> 3 & MASK_5BITS];                         // 5 
-        dest[d++] = (byte)alphabets[(p & MASK_3BITS) << 2 | (p=src[s++]) >>> 6 & MASK_2BITS]; // 3 2
-        dest[d++] = (byte)alphabets[p >>> 1 & MASK_5BITS];                                    //   5
-        dest[d++] = (byte)alphabets[(p & 1) << 4 | (p=src[s++]) >>> 4 & MASK_4BITS];          //   1 4
-        dest[d++] = (byte)alphabets[(p & MASK_4BITS) << 1 | (p=src[s++]) >>> 7 & 1];          //     4 1
-        dest[d++] = (byte)alphabets[p >>> 2 & MASK_5BITS];                                    //       5
-        dest[d++] = (byte)alphabets[(p & MASK_2BITS) << 3 | (p=src[s]) >>> 5 & MASK_3BITS];   //       2 3
-        dest[d] = (byte)alphabets[p & MASK_5BITS];                                            //         5
-        return;
-    }
-    
-    private final void encode4bytes(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s++]) >>> 3 & MASK_5BITS];                         // 5 
-        dest[d++] = (byte)alphabets[(p & MASK_3BITS) << 2 | (p=src[s++]) >>> 6 & MASK_2BITS]; // 3 2
-        dest[d++] = (byte)alphabets[p >>> 1 & MASK_5BITS];                                    //   5
-        dest[d++] = (byte)alphabets[(p & 1) << 4 | (p=src[s++]) >>> 4 & MASK_4BITS];          //   1 4
-        dest[d++] = (byte)alphabets[(p & MASK_4BITS) << 1 | (p=src[s]) >>> 7 & 1];            //     4 1
-        dest[d++] = (byte)alphabets[p >>> 2 & MASK_5BITS];                                    //       5
-        dest[d++] = (byte)alphabets[(p & MASK_2BITS) << 3];                                   //       2
-        dest[d] = PAD;
-        return;
-    }
-    
-    private final void encode3bytes(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s++]) >>> 3 & MASK_5BITS];                         // 5 
-        dest[d++] = (byte)alphabets[(p & MASK_3BITS) << 2 | (p=src[s++]) >>> 6 & MASK_2BITS]; // 3 2
-        dest[d++] = (byte)alphabets[p >>> 1 & MASK_5BITS];                                    //   5
-        dest[d++] = (byte)alphabets[(p & 1) << 4 | (p=src[s]) >>> 4 & MASK_4BITS];            //   1 4
-        dest[d++] = (byte)alphabets[(p & MASK_4BITS) << 1];                                   //     4
-        
-        for (int i=0; i < 3; i++)
-            dest[d++] = PAD;                                                                       
-        return;
-    }
-    
-    private final void encode2bytes(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s++]) >>> 3 & MASK_5BITS];                         // 5 
-        dest[d++] = (byte)alphabets[(p & MASK_3BITS) << 2 | (p=src[s]) >>> 6 & MASK_2BITS];   // 3 2
-        dest[d++] = (byte)alphabets[p >>> 1 & MASK_5BITS];                                    //   5
-        dest[d++] = (byte)alphabets[(p & 1) << 4];                                            //   1
-        
-        for (int i=0; i < 4; i++)
-            dest[d++] = PAD;                                                                       
-        return;
-    }
-    
-    private final void encode1byte(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s]) >>> 3 & MASK_5BITS];                            // 5 
-        dest[d++] = (byte)alphabets[(p & MASK_3BITS) << 2];                                    // 3
-        
-        for (int i=0; i < 6; i++)
-            dest[d++] = PAD;                                                                       
-        return;
-    }
-    
-    private final void decode5bytes(byte[] src, int s, byte[] dest, int d) {
-        int p=0;
-        // operator precedence in descending order: >>> or <<, &, |
-        dest[d++] = (byte)
-                    (
-                        pos(src[s++]) << 3
-                        | (p=pos(src[s++])) >>> 2 & MASK_3BITS
-                    )
-                    ;                                               // 5 3
-        dest[d++] = (byte)
-                    (
-                        (p & MASK_2BITS) << 6
-                        | pos(src[s++]) << 1 
-                        | (p=pos(src[s++])) >>> 4 & 1
-                    )
-                    ;                                               //   2 5 1
-        dest[d++] = (byte)
-                    (
-                        (p & MASK_4BITS) << 4 
-                        | (p=pos(src[s++])) >>> 1 & MASK_4BITS
-                    )
-                    ;                                               //       4 4
-        dest[d++] = (byte)
-                    (
-                        (p & 1) << 7
-                        | pos(src[s++]) << 2
-                        | (p=pos(src[s++])) >>> 3 & MASK_2BITS
-                    )
-                    ;                                               //         1 5 2
-        dest[d]   = (byte)
-                    (
-                        (p & MASK_3BITS) << 5 
-                        | pos(src[s])
-                    );                                              //             3 5
-        return;
-    }
-    
-    /**
-     * @param n the number of final quantum in bytes to decode into.  Ranges from 1 to 4, inclusive.
-     */
-    private final void decode1to4bytes(int n, byte[] src, int s, byte[] dest, int d) {
-        int p=0;
-        // operator precedence in descending order: >>> or <<, &, |
-        dest[d++] = (byte)
-                    (
-                        pos(src[s++]) << 3
-                        | (p=pos(src[s++])) >>> 2 & MASK_3BITS
-                    )
-                    ;                                               // 5 3
-        if (n == 1) {
-            sanityCheckLastPos(p, MASK_2BITS);
-            return;
-        }
-        
-        dest[d++] = (byte)
-                    (
-                        (p & MASK_2BITS) << 6
-                        | (pos(src[s++])) << 1 
-                        | (p=pos(src[s++])) >>> 4 & 1
-                    )
-                    ;                                               //   2 5 1
-        if (n == 2) {
-            sanityCheckLastPos(p, MASK_4BITS);
-            return;
-        }
-        
-        dest[d++] = (byte)
-                    (
-                        (p & MASK_4BITS) << 4 
-                        | (p=pos(src[s++])) >>> 1 & MASK_4BITS
-                    )
-                    ;                                               //       4 4
-        if (n == 3) {
-            sanityCheckLastPos(p, 1);
-            return;
-        }
-        
-        dest[d]   = (byte)
-                    (
-                        (p & 1) << 7
-                        | pos(src[s++]) << 2
-                        | (p=pos(src[s])) >>> 3 & MASK_2BITS
-                    )
-                    ;                                               //         1 5 2
-        sanityCheckLastPos(p, MASK_3BITS);
-        return;
-    }
-    
-    @Override
-    public final byte[] decode(byte[] src, final int length) 
-    {
-        if (length % 8 != 0)
-            throw new IllegalArgumentException
-            ("Input is expected to be encoded in multiple of 8 bytes but found: " + length);
-
-        int pads=0;
-        int last = length-1;
-        
-        // max possible padding in b32 encoding is 6
-        for (; pads < 6 && last > -1; last--, pads++) {
-            if (src[last] != PAD)
-                break;
-        }
-        
-        final int fq; // final quantum in unit of bytes
-        
-        switch(pads) {
-            case 0:
-                fq=5;
-                break; // final quantum of encoding input is an integral multiple of 40 bits
-            case 1:
-                fq=4;
-                break; // final quantum of encoding input is exactly 32 bits
-            case 3:
-                fq=3;
-                break; // final quantum of encoding input is exactly 24 bits
-            case 4:
-                fq=2;
-                break; // final quantum of encoding input is exactly 16 bits
-            case 6:
-                fq=1;
-                break; // final quantum of encoding input is exactly 8 bits
-            default:
-                throw new IllegalArgumentException("Invalid number of paddings " + pads);
-        }
-        final byte[] dest = new byte[length / 8 * 5 - (5-fq)]; 
-        int s=0, d=0;
-        
-        // % has a higher precedence than - than <
-        for (; d < dest.length - fq%5; s+=8,d+=5)
-            decode5bytes(src, s, dest, d);
-
-        if (fq < 5)
-            decode1to4bytes(fq, src, s, dest, d);
-        return dest;
-    }
-    
-    protected abstract int pos(byte in);
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/AwsHostNameUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AwsHostNameUtils.java
--- ./src/main/java/com/amazonaws/util/AwsHostNameUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AwsHostNameUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,247 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.net.InetAddress;
-import java.net.URI;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.amazonaws.internal.config.HostRegexToRegionMapping;
-import com.amazonaws.internal.config.InternalConfig;
-import com.amazonaws.log.InternalLogFactory;
-
-public class AwsHostNameUtils {
-
-    private static final Pattern S3_ENDPOINT_PATTERN =
-        Pattern.compile("^(?:.+\\.)?s3[.-]([a-z0-9-]+)$");
-
-    private static final Pattern STANDARD_CLOUDSEARCH_ENDPOINT_PATTERN =
-        Pattern.compile("^(?:.+\\.)?([a-z0-9-]+)\\.cloudsearch$");
-
-    private static final Pattern EXTENDED_CLOUDSEARCH_ENDPOINT_PATTERN =
-        Pattern.compile("^(?:.+\\.)?([a-z0-9-]+)\\.cloudsearch\\..+");
-
-    /**
-     * @deprecated in favor of {@link #parseRegionName(String, String)}.
-     */
-    @Deprecated
-    public static String parseRegionName(URI endpoint) {
-        return parseRegionName(endpoint.getHost(), null);
-    }
-
-    /**
-     * Attempts to parse the region name from an endpoint based on conventions
-     * about the endpoint format.
-     *
-     * @param host         the hostname to parse
-     * @param serviceHint  an optional hint about the service for the endpoint
-     * @return             the region parsed from the hostname, or
-     *                     &quot;us-east-1&quot; if no region information
-     *                     could be found.
-     * @deprecated	in favor of {@link #parseRegion(String, String)}.
-     */
-    @Deprecated
-    public static String parseRegionName(final String host,
-                                         final String serviceHint) {
-        String region = parseRegion(host, serviceHint);
-
-        // If region is null, then endpoint is totally non-standard;
-        // guess us-east-1 for lack of a better option.
-        return region == null ? "us-east-1" : region;
-    }
-
-    /**
-     * Attempts to parse the region name from an endpoint based on conventions
-     * about the endpoint format.
-     *
-     * @param host         the hostname to parse
-     * @param serviceHint  an optional hint about the service for the endpoint
-     * @return             the region parsed from the hostname, or
-     *                     null if no region information could be found.
-     */
-    public static String parseRegion(final String host,
-                                         final String serviceHint) {
-
-        if (host == null) {
-            throw new IllegalArgumentException("hostname cannot be null");
-        }
-        String regionNameInInternalConfig = parseRegionNameByInternalConfig(host);
-        if (regionNameInInternalConfig != null) {
-            return regionNameInInternalConfig;
-        }
-
-        if (host.endsWith(".amazonaws.com")) {
-            int index = host.length() - ".amazonaws.com".length();
-            return parseStandardRegionName(host.substring(0, index));
-        }
-
-        if (serviceHint != null) {
-            if (serviceHint.equals("cloudsearch")
-                    && !host.startsWith("cloudsearch.")) {
-
-                // CloudSearch domains use the nonstandard domain format
-                // [domain].[region].cloudsearch.[suffix].
-
-                Matcher matcher = EXTENDED_CLOUDSEARCH_ENDPOINT_PATTERN
-                        .matcher(host);
-
-                if (matcher.matches()) {
-                    return matcher.group(1);
-                }
-            }
-
-            // If we have a service hint, look for 'service.[region]' or
-            // 'service-[region]' in the endpoint's hostname.
-            Pattern pattern = Pattern.compile(
-                "^(?:.+\\.)?"
-                + Pattern.quote(serviceHint)
-                + "[.-]([a-z0-9-]+)\\."
-            );
-
-            Matcher matcher = pattern.matcher(host);
-            if (matcher.find()) {
-                return matcher.group(1);
-            }
-        }
-
-        // Endpoint is non-standard
-        return null;
-    }
-
-    /**
-     * Parses the region name from a standard (*.amazonaws.com) endpoint.
-     *
-     * @param fragment  the portion of the endpoint excluding
-     *                  &quot;.amazonaws.com&quot;
-     * @return          the parsed region name (or &quot;us-east-1&quot; as a
-     *                  best guess if we can't tell for sure)
-     */
-    private static String parseStandardRegionName(final String fragment) {
-
-        Matcher matcher = S3_ENDPOINT_PATTERN.matcher(fragment);
-        if (matcher.matches()) {
-            // host was 'bucket.s3-[region].amazonaws.com'.
-            return matcher.group(1);
-        }
-
-        matcher = STANDARD_CLOUDSEARCH_ENDPOINT_PATTERN.matcher(fragment);
-        if (matcher.matches()) {
-            // host was 'domain.[region].cloudsearch.amazonaws.com'.
-            return matcher.group(1);
-        }
-
-        int index = fragment.lastIndexOf('.');
-        if (index == -1) {
-            // host was 'service.amazonaws.com', guess us-east-1
-            // for lack of a better option.
-            return "us-east-1";
-        }
-
-        // host was 'service.[region].amazonaws.com'.
-        String region = fragment.substring(index + 1);
-
-        // Special case for iam.us-gov.amazonaws.com, which is actually
-        // us-gov-west-1.
-        if ("us-gov".equals(region)) {
-            region = "us-gov-west-1";
-        }
-
-        return region;
-    }
-
-    /**
-     * @return the configured region name if the given host name matches any of
-     *         the host-to-region mappings in the internal config; otherwise
-     *         return null.
-     */
-    private static String parseRegionNameByInternalConfig(String host) {
-        InternalConfig internConfig = InternalConfig.Factory.getInternalConfig();
-
-        for (HostRegexToRegionMapping mapping : internConfig.getHostRegexToRegionMappings()) {
-            if (mapping.isHostNameMatching(host)) {
-                return mapping.getRegionName();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Parses the service name from an endpoint. Can only handle endpoints of
-     * the form 'service.[region.]amazonaws.com'.
-     *
-     * @Deprecated This method currently doesn't support BJS endpoints. This
-     * method is used only in AWS4Signer to identify the service name from an
-     * endpoint. This method is broken as it no longer returns the service
-     * name to used for signing for all AWS services. This method will be
-     * removed as part of next major version upgrade.
-     */
-    @Deprecated
-    public static String parseServiceName(URI endpoint) {
-        String host = endpoint.getHost();
-
-        // If we don't recognize the domain, throw an exception.
-        if (!host.endsWith(".amazonaws.com")) {
-            throw new IllegalArgumentException(
-                "Cannot parse a service name from an unrecognized endpoint ("
-                + host
-                + ").");
-        }
-
-        String serviceAndRegion =
-            host.substring(0, host.indexOf(".amazonaws.com"));
-
-        // Special cases for S3 endpoints with bucket names embedded.
-        if (serviceAndRegion.endsWith(".s3")
-            || S3_ENDPOINT_PATTERN.matcher(serviceAndRegion).matches()) {
-            return "s3";
-        }
-
-        char separator = '.';
-
-        // If we don't detect a separator between service name and region, then
-        // assume that the region is not included in the hostname, and it's only
-        // the service name (ex: "http://iam.amazonaws.com").
-        if (serviceAndRegion.indexOf(separator) == -1) {
-            return serviceAndRegion;
-        }
-
-        String service =
-            serviceAndRegion.substring(0, serviceAndRegion.indexOf(separator));
-
-        return service;
-    }
-
-    /**
-     * Returns the host name for the local host. If the operation is not allowed
-     * by the security check, the textual representation of the IP address of
-     * the local host is returned instead. If the ip address of the local host
-     * cannot be resolved or if there is any other failure, "localhost" is
-     * returned as a fallback.
-     */
-    public static String localHostName() {
-        try {
-            InetAddress localhost = InetAddress.getLocalHost();
-            return localhost.getHostName();
-        } catch (Exception e) {
-            InternalLogFactory.getLog(AwsHostNameUtils.class)
-                .debug(
-                    "Failed to determine the local hostname; fall back to "
-                            + "use \"localhost\".", e);
-            return "localhost";
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/AWSRequestMetricsFullSupport.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AWSRequestMetricsFullSupport.java
--- ./src/main/java/com/amazonaws/util/AWSRequestMetricsFullSupport.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AWSRequestMetricsFullSupport.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,226 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.util;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.metrics.AwsSdkMetrics;
-import com.amazonaws.metrics.MetricType;
-import com.amazonaws.metrics.RequestMetricCollector;
-
-/**
- * In contrast to {@link AWSRequestMetrics}, which is intended to be a minimal
- * support of AWS SDK request metrics, this class is the full support of AWS SDK
- * request metrics including features such as properties and sub-events.
- * <p>
- * This class is instantiated instead of {@link AWSRequestMetrics} when request
- * metric collection is required during a particular service request/response
- * cycle.
- */
-@NotThreadSafe
-public class AWSRequestMetricsFullSupport extends AWSRequestMetrics {
-    /* Stores some key value pairs. */
-    private final Map<String, List<Object>> properties = new HashMap<String, List<Object>>();
-    
-    /* A map to store events that are being profiled. */
-    private final Map<String, TimingInfo> eventsBeingProfiled = new HashMap<String, TimingInfo>();
-    /* Latency Logger */
-    private static final Log latencyLogger = LogFactory.getLog("com.amazonaws.latency");
-    private static final Object KEY_VALUE_SEPARATOR = "=";
-    private static final Object COMMA_SEPARATOR = ", ";
-
-    /**
-     * This constructor should be used in the case when AWS SDK metrics
-     * collector is enabled.
-     * 
-     * @see AWSRequestMetricsFullSupport
-     */
-    public AWSRequestMetricsFullSupport() {
-        super(TimingInfo.startTimingFullSupport());
-    }
-    
-    /**
-     * Start an event which will be timed. The startTime and endTime are added
-     * to timingInfo only after endEvent is called. For every startEvent there
-     * should be a corresponding endEvent. If you start the same event without
-     * ending it, this will overwrite the old event. i.e. There is no support
-     * for recursive events yet. Having said that, if you start and end an event
-     * in that sequence multiple times, all events are logged in timingInfo in
-     * that order.
-     * 
-     * This feature is enabled if the system property
-     * "com.amazonaws.sdk.enableRuntimeProfiling" is set, or if a
-     * {@link RequestMetricCollector} is in use either at the request, web service
-     * client, or AWS SDK level.
-     * 
-     * @param eventName
-     *            - The name of the event to start
-     * 
-     * @see AwsSdkMetrics
-     */
-    @Override
-    public void startEvent(String eventName) {
-        /* This will overwrite past events */
-        eventsBeingProfiled.put // ignoring the wall clock time
-            (eventName, TimingInfo.startTimingFullSupport(System.nanoTime()));
-    }
-
-    @Override
-    public void startEvent(MetricType f) {
-        startEvent(f.name());
-    }
-
-    /**
-     * End an event which was previously started. Once ended, log how much time
-     * the event took. It is illegal to end an Event that was not started. It is
-     * good practice to endEvent in a finally block. See Also startEvent.
-     * 
-     * @param eventName
-     *            - The name of the event to start
-     */
-    @Override
-    public void endEvent(String eventName) {
-        TimingInfo event = eventsBeingProfiled.get(eventName);
-        /* Somebody tried to end an event that was not started. */
-        if (event == null) {
-            LogFactory.getLog(getClass()).warn
-                ("Trying to end an event which was never started: " + eventName);
-            return;
-        }
-        event.endTiming();
-        this.timingInfo.addSubMeasurement(
-            eventName,
-            TimingInfo.unmodifiableTimingInfo(
-                event.getStartTimeNano(),
-                event.getEndTimeNano()));
-    }
-
-    @Override
-    public void endEvent(MetricType f) {
-        endEvent(f.name());
-    }
-
-    /**
-     * Add 1 to an existing count for a given event. If the count for that event
-     * does not exist, then it creates one and initializes it to 1.
-     * 
-     * This feature is enabled if the system property
-     * "com.amazonaws.sdk.enableRuntimeProfiling" is set, or if a
-     * {@link RequestMetricCollector} is in use either at the request, web service
-     * client, or AWS SDK level.
-     * 
-     * @param event
-     *            - The name of the event to count
-     */
-    @Override
-    public void incrementCounter(String event) {
-        timingInfo.incrementCounter(event);
-    }
-
-    @Override
-    public void incrementCounter(MetricType f) {
-        incrementCounter(f.name());
-    }
-    
-    @Override
-    public void setCounter(String counterName, long count) {
-        timingInfo.setCounter(counterName, count);
-    }
-
-    @Override
-    public void setCounter(MetricType f, long count) {
-        setCounter(f.name(), count);
-    }
-    
-    /**
-     * Add a property. If you add the same property more than once, it stores
-     * all values a list.
-     * 
-     * This feature is enabled if the system property
-     * "com.amazonaws.sdk.enableRuntimeProfiling" is set, or if a
-     * {@link RequestMetricCollector} is in use either at the request, web service
-     * client, or AWS SDK level.
-     * 
-     * @param propertyName
-     *            The name of the property
-     * @param value
-     *            The property value
-     */
-    @Override
-    public void addProperty(String propertyName, Object value) {
-        List<Object> propertyList = properties.get(propertyName);
-        if (propertyList == null) {
-            propertyList = new ArrayList<Object>();
-            properties.put(propertyName, propertyList);
-        }
-        
-        propertyList.add(value);
-    }
-
-    @Override
-    public void addProperty(MetricType f, Object value) {
-        addProperty(f.name(), value);
-    }
-
-    @Override
-    public void log() {
-        if (latencyLogger.isInfoEnabled()) {
-            StringBuilder builder = new StringBuilder();
-
-            for (Entry<String, List<Object>> entry : properties.entrySet()) {
-                keyValueFormat(entry.getKey(), entry.getValue(), builder);
-            }
-
-            for (Entry<String, Number> entry : timingInfo.getAllCounters()
-                    .entrySet()) {
-                keyValueFormat(entry.getKey(), entry.getValue(), builder);
-            }
-            for (Entry<String, List<TimingInfo>> entry : timingInfo
-                    .getSubMeasurementsByName().entrySet()) {
-                keyValueFormat(entry.getKey(), entry.getValue(), builder);
-            }
-            latencyLogger.info(builder.toString());
-        }
-    }
-
-    private void keyValueFormat(Object key, Object value, StringBuilder builder) {
-        builder.append(key).append(KEY_VALUE_SEPARATOR).append(value).append(COMMA_SEPARATOR);
-    }
-
-    @Override
-    public List<Object> getProperty(String propertyName){
-    	return properties.get(propertyName);
-    }
-
-    @Override
-    public List<Object> getProperty(MetricType f){
-        return getProperty(f.name());
-    }
-
-    /** Always returns true. */
-    @Override
-    public final boolean isEnabled() {
-        return true;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/AWSRequestMetrics.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AWSRequestMetrics.java
--- ./src/main/java/com/amazonaws/util/AWSRequestMetrics.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AWSRequestMetrics.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,232 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.util;
-
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.metrics.MetricType;
-import com.amazonaws.metrics.RequestMetricType;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Used as both a base class and a minimal support of AWS SDK request metrics.
- * The base class of supporting AWS SDK request metrics.
- * <p>
- * In contrast to {@link AWSRequestMetricsFullSupport}, which is intended to be
- * a full support of AWS SDK request metrics, this class only provides access to
- * a {@link TimingInfo} instance that only has minimal support for start and end
- * time (ie with no-ops for sub-event measurements) for backward compatibility
- * reason. The other methods related to properties and counters in this class
- * are effectively no-ops.
- * <p>
- * This class is instantiated instead of {@link AWSRequestMetricsFullSupport}
- * when request metric collection is not required during a particular service
- * request/response cycle.
- */
-@NotThreadSafe
-public class AWSRequestMetrics {
-    /**
-     *  If the class name is required for logging and metrics we should use this
-     *  constant version instead of the expensive function call.
-     */
-    public static final String SIMPLE_NAME = AWSRequestMetrics.class.getSimpleName();
-
-    /**
-     * Predefined AWS SDK metric types general across all AWS clients. Client
-     * specific predefined metrics like S3 or DynamoDB are defined in the client
-     * specific packages.
-     */
-    public enum Field implements RequestMetricType {
-        AWSErrorCode,
-        AWSRequestID,
-        /**
-         * The specific request subtype, such as PutItemRequest, PutObjectRequest, etc.
-         */
-        RequestType,
-        BytesProcessed,
-        /**
-         * Total number of milliseconds taken for a request/response including
-         * the time taken to execute the request handlers, round trip to AWS,
-         * and the time taken to execute the response handlers.
-         */
-        ClientExecuteTime,
-        CredentialsRequestTime,
-
-        Exception,
-        /**
-         * Used to count and preserve the throttle related exceptions.
-         */
-        ThrottleException,
-        /**
-         * Number of milliseconds taken for a request/response round trip to AWS.
-         */
-        HttpRequestTime,
-        RedirectLocation,
-        RequestMarshallTime,
-        /**
-         * Number of milliseconds taken to sign a request.
-         */
-        RequestSigningTime,
-        /**
-         * Number of milliseconds taken to execute the response handler for a response from AWS.
-         */
-        ResponseProcessingTime,
-        /**
-         * Number of requests to AWS.
-         */
-        RequestCount,
-        /**
-         * Number of retries of AWS SDK sending a request to AWS.
-         */
-        RetryCount, // captured via the RequestCount since (RetryCount = RequestCount - 1)
-        /**
-         * Snapshot of currently consumed retry capacity.
-         */
-        RetryCapacityConsumed,
-        /**
-         * Number of retries that were not attempted due to retry throttling.
-         */
-        ThrottledRetryCount,
-        /**
-         * Number of retries of the underlying http client library in sending a
-         * request to AWS.
-         */
-        HttpClientRetryCount,
-        /**
-         * Time taken to send a request to AWS by the http client library,
-         * excluding any retry.
-         */
-        HttpClientSendRequestTime,
-        /**
-         * Time taken to receive a response from AWS by the http client library,
-         * excluding any retry.
-         */
-        HttpClientReceiveResponseTime,
-
-        /**
-         * Time taken for socket to read.
-         */
-        HttpSocketReadTime,
-
-        /**
-         * The number of idle persistent connections.
-         * <p>
-         * Reference: https://hc.apache
-         * .org/httpcomponents-core-ga/httpcore/apidocs/org/apache
-         * /http/pool/PoolStats.html
-         */
-        HttpClientPoolAvailableCount,
-        /**
-         * The number of persistent connections tracked by the connection
-         * manager currently being used to execute requests.
-         * <p>
-         * Reference: https://hc
-         * .apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache
-         * /http/pool/PoolStats.html
-         */
-        HttpClientPoolLeasedCount,
-        /**
-         * The number of connection requests being blocked awaiting a free
-         * connection.
-         * <p>
-         * Reference: https://hc.apache.org/httpcomponents-core-ga/httpcore
-         * /apidocs/org/apache/http/pool/PoolStats.html
-         */
-        HttpClientPoolPendingCount,
-        RetryPauseTime,
-        ServiceEndpoint,
-        ServiceName,
-        StatusCode, // The http status code
-        ;
-    }
-
-    protected final TimingInfo timingInfo;
-
-    /**
-     * This constructor should be used only in the case when AWS SDK metrics
-     * collector is disabled, when minimal timing info is supported for backward
-     * compatibility reasons.
-     *
-     * @see AWSRequestMetricsFullSupport
-     */
-    public AWSRequestMetrics() {
-        this.timingInfo = TimingInfo.startTiming();
-    }
-
-    protected AWSRequestMetrics(TimingInfo timingInfo) {
-        this.timingInfo = timingInfo;
-    }
-
-    public final TimingInfo getTimingInfo() {
-        return timingInfo;
-    }
-    /**
-     * Returns true if this metrics is enabled; false otherwise.
-     * Returns false by default.
-     * */
-    public boolean isEnabled() {
-        return false;
-    }
-
-    public void startEvent(String eventName) {}
-    public void startEvent(MetricType f) {}
-    public void endEvent(String eventName) {}
-    public void endEvent(MetricType f) {}
-
-    public void incrementCounter(String event) {}
-    public void incrementCounter(MetricType f) {}
-    /** Fluent API of {@link #incrementCounter(String)} */
-    public final AWSRequestMetrics incrementCounterWith(String event) {
-        incrementCounter(event);
-        return this;
-    }
-    /** Fluent API of {@link #incrementCounter(MetricType)} */
-    public final AWSRequestMetrics incrementCounterWith(MetricType f) {
-        incrementCounter(f);
-        return this;
-    }
-
-    public void setCounter(String counterName, long count) {}
-    public void setCounter(MetricType f, long count) {}
-    /** Fluent API of {@link #setCounter(String, long)} */
-    public final AWSRequestMetrics withCounter(String counterName, long count) {
-        setCounter(counterName, count);
-        return this;
-    }
-    /** Fluent API of {@link #setCounter(MetricType, long)} */
-    public final AWSRequestMetrics withCounter(MetricType f, long count) {
-        setCounter(f, count);
-        return this;
-    }
-
-    public void addProperty(String propertyName, Object value) {}
-    public void addProperty(MetricType f, Object value) {}
-    /** Fluent API of {@link #addProperty(String, Object)} */
-    public final AWSRequestMetrics addPropertyWith(String propertyName, Object value) {
-        addProperty(propertyName, value);
-        return this;
-    }
-    /** Fluent API of {@link #addProperty(MetricType, Object)} */
-    public final AWSRequestMetrics addPropertyWith(MetricType f, Object value) {
-        addProperty(f, value);
-        return this;
-    }
-
-    public void log() {}
-    public List<Object> getProperty(String propertyName){ return Collections.emptyList(); }
-    public List<Object> getProperty(MetricType f) { return Collections.emptyList(); }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/AWSServiceMetrics.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AWSServiceMetrics.java
--- ./src/main/java/com/amazonaws/util/AWSServiceMetrics.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/AWSServiceMetrics.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,37 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.util;
-
-import com.amazonaws.metrics.ServiceMetricType;
-
-/**
- * Predefined AWS SDK non-request specific metric types general across all AWS
- * clients. Client specific predefined metrics like S3 or DynamoDB are defined
- * in the client specific packages.
- */
-public enum AWSServiceMetrics implements ServiceMetricType {
-    /**
-     * Time taken to get a connection by the http client library.
-     */
-    HttpClientGetConnectionTime("HttpClient"),
-    ;
-
-    private final String serviceName;
-    private AWSServiceMetrics(String serviceName) {
-        this.serviceName = serviceName;
-    }
-    @Override public String getServiceName() { return serviceName; }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base16Codec.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base16Codec.java
--- ./src/main/java/com/amazonaws/util/Base16Codec.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base16Codec.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,102 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * A Base 16 codec implementation.
- *
- * @author Hanson Char
- */
-class Base16Codec implements Codec {
-    private static final int OFFSET_OF_a = 'a' - 10;
-    private static final int OFFSET_OF_A = 'A' - 10;
-    private static final int MASK_4BITS = (1 << 4) - 1;
-
-    private static class LazyHolder {
-        private static final byte[] DECODED = decodeTable();
-
-        private static byte[] decodeTable() {
-            final byte[] dest = new byte['f'+1];
-
-            for (int i=0; i <= 'f'; i++)
-            {
-                if (i >= '0' && i <= '9')
-                    dest[i] = (byte)(i - '0');
-                else if (i >= 'A' && i <= 'F')
-                    dest[i] = (byte)(i - OFFSET_OF_A);
-                else if (i >= 'a' && i <= 'f')
-                    dest[i] = (byte)(i - OFFSET_OF_a);
-                else
-                    dest[i] = -1;
-            }
-            return dest;
-        }
-    }
-
-    private final byte[] alphabets;
-
-    Base16Codec() {
-        this(true);
-    }
-
-    Base16Codec(boolean upperCase) {
-        this.alphabets = upperCase
-                  ? CodecUtils.toBytesDirect("0123456789ABCDEF")
-                  : CodecUtils.toBytesDirect("0123456789abcdef");
-    }
-
-    @Override
-    public byte[] encode(byte[] src) {
-        byte[] dest = new byte[src.length * 2];
-        byte p;
-
-        for (int i=0,j=0; i < src.length; i++) {
-            dest[j++] = (byte)alphabets[(p=src[i]) >>> 4 & MASK_4BITS];
-            dest[j++] = (byte)alphabets[p & MASK_4BITS];
-        }
-        return dest;
-    }
-
-    @Override
-    public byte[] decode(byte[] src, final int length)
-    {
-        if (length % 2 != 0) {
-            throw new IllegalArgumentException(
-                "Input is expected to be encoded in multiple of 2 bytes but found: "
-                + length
-            );
-        }
-        final byte[] dest = new byte[length / 2];
-
-        for (int i=0, j=0; j < dest.length; j++)
-        {
-            dest[j] = (byte)
-                    (
-                        pos(src[i++]) << 4 | pos(src[i++])
-                    )
-                    ;
-
-        }
-        return dest;
-    }
-
-    protected int pos(byte in) {
-        int pos = LazyHolder.DECODED[in];
-
-        if (pos > -1)
-            return pos;
-        throw new IllegalArgumentException("Invalid base 16 character: \'" + (char)in + "\'");
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base16.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base16.java
--- ./src/main/java/com/amazonaws/util/Base16.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base16.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * A Base 16 codec API, which encodes into hex string in upper case.
- *
- * See http://www.ietf.org/rfc/rfc4648.txt
- *
- * @author Hanson Char
- */
-public enum Base16 {
-    ;
-    private static final Base16Codec codec = new Base16Codec();
-
-    /**
-     * Returns a base 16 encoded string (in upper case) of the given bytes.
-     */
-    public static String encodeAsString(byte ... bytes) {
-        if (bytes == null)
-            return null;
-        return bytes.length == 0 ? "" : CodecUtils.toStringDirect(codec.encode(bytes));
-    }
-
-    /**
-     * Returns a base 16 encoded byte array of the given bytes.
-     */
-    public static byte[] encode(byte[] bytes) { return bytes == null || bytes.length == 0 ? bytes : codec.encode(bytes); }
-
-    /**
-     * Decodes the given base 16 encoded string,
-     * skipping carriage returns, line feeds and spaces as needed.
-     */
-    public static byte[] decode(String b16) {
-        if (b16 == null)
-            return null;
-        if (b16.length() == 0)
-            return new byte[0];
-        byte[] buf = new byte[b16.length()];
-        int len = CodecUtils.sanitize(b16, buf);
-        return codec.decode(buf, len);
-    }
-
-    /**
-     * Decodes the given base 16 encoded bytes.
-     */
-    public static byte[] decode(byte[] b16) { return b16 == null || b16.length == 0 ? b16 :  codec.decode(b16, b16.length); }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base16Lower.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base16Lower.java
--- ./src/main/java/com/amazonaws/util/Base16Lower.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base16Lower.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * A Base 16 codec API, which encodes into hex string in lower case.
- *
- * See http://www.ietf.org/rfc/rfc4648.txt
- *
- * @author Hanson Char
- */
-public enum Base16Lower {
-    ;
-    private static final Base16Codec codec = new Base16Codec(false);
-
-    /**
-     * Returns a base 16 encoded string (in lower case) of the given bytes.
-     */
-    public static String encodeAsString(byte ... bytes) {
-        if (bytes == null)
-            return null;
-        return bytes.length == 0 ? "" : CodecUtils.toStringDirect(codec.encode(bytes));
-    }
-
-    /**
-     * Returns a base 16 encoded byte array of the given bytes.
-     */
-    public static byte[] encode(byte[] bytes) { return bytes == null || bytes.length == 0 ? bytes : codec.encode(bytes); }
-
-    /**
-     * Decodes the given base 16 encoded string,
-     * skipping carriage returns, line feeds and spaces as needed.
-     */
-    public static byte[] decode(String b16) {
-        if (b16 == null)
-            return null;
-        if (b16.length() == 0)
-            return new byte[0];
-        byte[] buf = new byte[b16.length()];
-        int len = CodecUtils.sanitize(b16, buf);
-        return codec.decode(buf, len);
-    }
-
-    /**
-     * Decodes the given base 16 encoded bytes.
-     */
-    public static byte[] decode(byte[] b16) { return b16 == null || b16.length == 0 ? b16 :  codec.decode(b16, b16.length); }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base32Codec.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base32Codec.java
--- ./src/main/java/com/amazonaws/util/Base32Codec.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base32Codec.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,63 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * A Base 32 codec implementation.
- * 
- * @author Hanson Char
- */
-class Base32Codec extends AbstractBase32Codec {
-    private static final int OFFSET_OF_2 = '2' - 26;
-    
-    private static class LazyHolder {
-        private static final byte[] DECODED = decodeTable();
-        
-        private static byte[] decodeTable() {
-            final byte[] dest = new byte['z'+1];
-            
-            for (int i=0; i <= 'z'; i++) 
-            {
-                if (i >= 'A' && i <= 'Z')
-                    dest[i] = (byte)(i - 'A');
-                else if (i >= '2' && i <= '7')
-                    dest[i] = (byte)(i - OFFSET_OF_2);
-                else if (i >= 'a' && i <= 'z')
-                    dest[i] = (byte)(i - 'a');
-                else 
-                    dest[i] = -1;
-            }
-            return dest;
-        }
-    }
-
-    private static byte[] alphabets() {
-        // Base 32 alphabet as defined at http://www.ietf.org/rfc/rfc4648.txt
-        return CodecUtils.toBytesDirect("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
-    }
-
-    Base32Codec() {
-        super(alphabets());
-    }
-    
-    @Override
-    protected int pos(byte in) {
-        int pos = LazyHolder.DECODED[in];
-        
-        if (pos > -1)
-            return pos;
-        throw new IllegalArgumentException("Invalid base 32 character: \'" + (char)in + "\'");
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base32.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base32.java
--- ./src/main/java/com/amazonaws/util/Base32.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base32.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * A Base 32 codec API.
- * 
- * See http://www.ietf.org/rfc/rfc4648.txt
- * 
- * @author Hanson Char
- */
-public enum Base32 {
-    ;
-    private static final Base32Codec codec = new Base32Codec();
-    
-    /**
-     * Returns a base 32 encoded string of the given bytes.
-     */
-    public static String encodeAsString(byte ... bytes) {
-        if (bytes == null)
-            return null;
-        return bytes.length == 0 ? "" : CodecUtils.toStringDirect(codec.encode(bytes)); 
-    }
-    
-    /**
-     * Returns a 32 encoded byte array of the given bytes.
-     */
-    public static byte[] encode(byte[] bytes) { return bytes == null || bytes.length == 0 ? bytes : codec.encode(bytes); }
-    
-    /** 
-     * Decodes the given base 32 encoded string,
-     * skipping carriage returns, line feeds and spaces as needed.
-     */
-    public static byte[] decode(String b32) {
-        if (b32 == null)
-            return null;
-        if (b32.length() == 0)
-            return new byte[0];
-        byte[] buf = new byte[b32.length()];
-        int len = CodecUtils.sanitize(b32, buf);
-        return codec.decode(buf, len);
-    }
-    
-    /** 
-     * Decodes the given base 32 encoded bytes.
-     */
-    public static byte[] decode(byte[] b32) { return b32 == null || b32.length == 0 ? b32 :  codec.decode(b32, b32.length); }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base64Codec.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base64Codec.java
--- ./src/main/java/com/amazonaws/util/Base64Codec.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base64Codec.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,244 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-import static com.amazonaws.util.CodecUtils.sanityCheckLastPos;
-
-/**
- * A Base 64 codec implementation.
- * 
- * @author Hanson Char
- */
-class Base64Codec implements Codec {
-    private static final int OFFSET_OF_a = 'a' - 26;
-    private static final int OFFSET_OF_0 = '0' - 52;
-    private static final int OFFSET_OF_PLUS = '+' - 62;
-    private static final int OFFSET_OF_SLASH = '/' - 63;
-    
-    private static final int MASK_2BITS = (1 << 2) - 1;
-    private static final int MASK_4BITS = (1 << 4) - 1;
-    private static final int MASK_6BITS = (1 << 6) - 1;
-    // Alphabet as defined at http://www.ietf.org/rfc/rfc4648.txt
-    private static final byte PAD = '=';
-    
-    private static class LazyHolder {
-        private static final byte[] DECODED = decodeTable();
-        
-        private static byte[] decodeTable() {
-            final byte[] dest = new byte['z'+1];
-            
-            for (int i=0; i <= 'z'; i++) 
-            {
-                if (i >= 'A' && i <= 'Z')
-                    dest[i] = (byte)(i - 'A');
-                else if (i >= '0' && i <= '9')
-                    dest[i] = (byte)(i - OFFSET_OF_0);
-                else if (i == '+')
-                    dest[i] = (byte)(i - OFFSET_OF_PLUS);
-                else if (i == '/')
-                    dest[i] = (byte)(i - OFFSET_OF_SLASH);
-                else if (i >= 'a' && i <= 'z')
-                    dest[i] = (byte)(i - OFFSET_OF_a);
-                else 
-                    dest[i] = -1;
-            }
-            return dest;
-        }
-    }
-
-    private final byte[] alphabets;
-
-    Base64Codec() {
-        this.alphabets = CodecUtils.toBytesDirect("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
-    }
-    
-    protected Base64Codec(byte[] alphabets) {
-        this.alphabets = alphabets;
-    }
-
-    @Override
-    public byte[] encode(byte[] src) {
-        final int num3bytes = src.length / 3;
-        final int remainder = src.length % 3;
-        
-        if (remainder == 0)
-        {
-            byte[] dest = new byte[num3bytes * 4];
-    
-            for (int s=0,d=0; s < src.length; s+=3, d+=4)
-                encode3bytes(src, s, dest, d);
-            return dest;
-        }
-        
-        byte[] dest = new byte[(num3bytes+1) * 4];
-        int s=0, d=0;
-        
-        for (; s < src.length-remainder; s+=3, d+=4)
-            encode3bytes(src, s, dest, d);
-        
-        switch(remainder) {
-            case 1:
-                encode1byte(src, s, dest, d);
-                break;
-            case 2:
-                encode2bytes(src, s, dest, d);
-                break;
-            default:
-                throw new IllegalStateException();
-        }
-        return dest;
-    }
-    
-    void encode3bytes(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s++]) >>> 2 & MASK_6BITS];                         // 6 
-        dest[d++] = (byte)alphabets[(p & MASK_2BITS) << 4 | (p=src[s++]) >>> 4 & MASK_4BITS]; // 2 4
-        dest[d++] = (byte)alphabets[(p & MASK_4BITS) << 2 | (p=src[s]) >>> 6 & MASK_2BITS];   //   4 2
-        dest[d] = (byte)alphabets[p & MASK_6BITS];                                            //     6
-        return;
-    }
-    
-    void encode2bytes(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s++]) >>> 2 & MASK_6BITS];                         // 6 
-        dest[d++] = (byte)alphabets[(p & MASK_2BITS) << 4 | (p=src[s]) >>> 4 & MASK_4BITS];   // 2 4
-        dest[d++] = (byte)alphabets[(p & MASK_4BITS) << 2];                                   //   4
-        dest[d] = PAD;
-        return;
-    }
-    
-    void encode1byte(byte[] src, int s, byte[] dest, int d) {
-        // operator precedence in descending order: >>> or <<, &, |
-        byte p;
-        dest[d++] = (byte)alphabets[(p=src[s]) >>> 2 & MASK_6BITS];                           // 6 
-        dest[d++] = (byte)alphabets[(p & MASK_2BITS) << 4];                                   // 2
-        dest[d++] = PAD;
-        dest[d] = PAD;
-        return;
-    }
-    
-    void decode4bytes(byte[] src, int s, byte[] dest, int d) {
-        int p=0;
-        // operator precedence in descending order: >>> or <<, &, |
-        dest[d++] = (byte)
-                    (
-                        pos(src[s++]) << 2
-                        | (p=pos(src[s++])) >>> 4 & MASK_2BITS
-                    )
-                    ;                                               // 6 2
-        dest[d++] = (byte)
-                    (
-                        (p & MASK_4BITS) << 4 
-                        | (p=pos(src[s++])) >>> 2 & MASK_4BITS
-                    )
-                    ;                                               //   4 4
-        dest[d] = (byte)
-                    (
-                        (p & MASK_2BITS) << 6
-                        | pos(src[s])
-                    )
-                    ;                                               //     2 6
-        return;
-    }
-    
-    /**
-     * @param n the number of final quantum in bytes to decode into.  Ranges from 1 to 3, inclusive.
-     */
-    void decode1to3bytes(int n, byte[] src, int s, byte[] dest, int d) {
-        int p=0;
-        // operator precedence in descending order: >>> or <<, &, |
-        dest[d++] = (byte)
-                    (
-                        pos(src[s++]) << 2
-                        | (p=pos(src[s++])) >>> 4 & MASK_2BITS
-                    )
-                    ;                                               // 6 2
-        if (n == 1) {
-            sanityCheckLastPos(p, MASK_4BITS);
-            return;
-        }
-        
-        dest[d++] = (byte)
-                    (
-                        (p & MASK_4BITS) << 4 
-                        | (p=pos(src[s++])) >>> 2 & MASK_4BITS
-                    )
-                    ;                                               //   4 4
-        if (n == 2) {
-            sanityCheckLastPos(p, MASK_2BITS);
-            return;
-        }
-        
-        dest[d] = (byte)
-                    (
-                        (p & MASK_2BITS) << 6
-                        | pos(src[s])
-                    )
-                    ;                                               //     2 6
-        return;
-    }
-
-    @Override
-    public byte[] decode(byte[] src, final int length) 
-    {
-        if (length % 4 != 0)
-            throw new IllegalArgumentException
-            ("Input is expected to be encoded in multiple of 4 bytes but found: " + length);
-
-        int pads=0;
-        int last = length-1;
-        
-        // max possible padding in b64 encoding is 2
-        for (; pads < 2 && last > -1; last--, pads++) {
-            if (src[last] != PAD)
-                break;
-        }
-        
-        final int fq; // final quantum in unit of bytes
-        
-        switch(pads) {
-            case 0:
-                fq=3;
-                break; // final quantum of encoding input is an integral multiple of 24 bits
-            case 1:
-                fq=2;
-                break; // final quantum of encoding input is exactly 16 bits
-            case 2:
-                fq=1;
-                break; // final quantum of encoding input is exactly 8 bits
-            default:
-                throw new Error("Impossible");
-        }
-        final byte[] dest = new byte[length / 4 * 3 - (3-fq)]; 
-        int s=0, d=0;
-        
-        // % has a higher precedence than - than <
-        for (; d < dest.length - fq%3; s+=4,d+=3)
-            decode4bytes(src, s, dest, d);
-
-        if (fq < 3)
-            decode1to3bytes(fq, src, s, dest, d);
-        return dest;
-    }
-    
-    protected int pos(byte in) {
-        int pos = LazyHolder.DECODED[in];
-        
-        if (pos > -1)
-            return pos;
-        throw new IllegalArgumentException("Invalid base 64 character: \'" + (char)in + "\'");
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Base64.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base64.java
--- ./src/main/java/com/amazonaws/util/Base64.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Base64.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,96 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import javax.xml.bind.DatatypeConverter;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-
-import com.amazonaws.log.InternalLogApi;
-import com.amazonaws.log.InternalLogFactory;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A Base 64 codec API.
- *
- * See http://www.ietf.org/rfc/rfc4648.txt
- *
- * @author Hanson Char
- */
-public enum Base64 {
-    ;
-    private static final InternalLogApi LOG = InternalLogFactory.getLog(Base64.class);
-    private static final Base64Codec codec = new Base64Codec();
-
-    static {
-        Map<String,String> inconsistentJaxbImpls = new HashMap<String, String>();
-        inconsistentJaxbImpls.put("org.apache.ws.jaxme.impl.JAXBContextImpl", "Apache JaxMe");
-
-        try {
-            String className = JAXBContext.newInstance().getClass().getName();
-            if (inconsistentJaxbImpls.values().contains(className)) {
-                LOG.warn("A JAXB implementation known to produce base64 encodings that are " +
-                        "inconsistent with the reference implementation has been detected. The " +
-                        "results of the encodeAsString() method may be incorrect. Implementation: " +
-                        inconsistentJaxbImpls.get(className));
-            }
-        } catch (JAXBException ignored) {
-        }
-    }
-
-    /**
-     * Returns a base 64 encoded string of the given bytes.
-     */
-    public static String encodeAsString(byte ... bytes) {
-        if (bytes == null)
-            return null;
-        try {
-            return DatatypeConverter.printBase64Binary(bytes);
-        } catch (NullPointerException ex) {
-            // https://netbeans.org/bugzilla/show_bug.cgi?id=224923
-            // https://issues.apache.org/jira/browse/CAMEL-4893
-
-            // Note the converter should eventually be initialized and printBase64Binary should start working again
-            LOG.debug("Recovering from JAXB bug: https://netbeans.org/bugzilla/show_bug.cgi?id=224923", ex);
-        }
-        return bytes.length == 0 ? "" : CodecUtils.toStringDirect(codec.encode(bytes));
-    }
-
-    /**
-     * Returns a 64 encoded byte array of the given bytes.
-     */
-    public static byte[] encode(byte[] bytes) { return bytes == null || bytes.length == 0 ? bytes : codec.encode(bytes); }
-
-    /**
-     * Decodes the given base 64 encoded string,
-     * skipping carriage returns, line feeds and spaces as needed.
-     */
-    public static byte[] decode(String b64) {
-        if (b64 == null)
-            return null;
-        if (b64.length() == 0)
-            return new byte[0];
-        byte[] buf = new byte[b64.length()];
-        int len = CodecUtils.sanitize(b64, buf);
-        return codec.decode(buf, len);
-    }
-
-    /**
-     * Decodes the given base 64 encoded bytes.
-     */
-    public static byte[] decode(byte[] b64) { return b64 == null || b64.length == 0 ? b64 :  codec.decode(b64, b64.length); }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/BasicNameValuePair.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/BasicNameValuePair.java
--- ./src/main/java/com/amazonaws/util/BasicNameValuePair.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/BasicNameValuePair.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,123 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package com.amazonaws.util;
-
-import java.io.Serializable;
-
-import com.amazonaws.annotation.Immutable;
-
-/**
- * Basic implementation of {@link NameValuePair}.
- *
- * @since 4.0
- */
-@Immutable
-class BasicNameValuePair implements NameValuePair, Cloneable, Serializable {
-    private static final long serialVersionUID = 1L;
-    public static final int HASH_SEED = 17;
-    public static final int HASH_OFFSET = 37;
-
-    private final String name;
-    private final String value;
-
-    /**
-     * Default Constructor taking a name and a value. The value may be null.
-     *
-     * @param name The name.
-     * @param value The value.
-     */
-    BasicNameValuePair(final String name, final String value) {
-        if (name == null)
-            throw new IllegalArgumentException("Name must not be null");
-        this.name = name;
-        this.value = value;
-    }
-
-    @Override
-    public String getName() {
-        return this.name;
-    }
-
-    @Override
-    public String getValue() {
-        return this.value;
-    }
-
-    @Override
-    public String toString() {
-        // don't call complex default formatting for a simple toString
-
-        if (this.value == null) {
-            return name;
-        }
-        final int len = this.name.length() + 1 + this.value.length();
-        final StringBuilder buffer = new StringBuilder(len);
-        buffer.append(this.name);
-        buffer.append("=");
-        buffer.append(this.value);
-        return buffer.toString();
-    }
-
-    @Override
-    public boolean equals(final Object object) {
-        if (this == object) {
-            return true;
-        }
-        if (object instanceof NameValuePair) {
-            final BasicNameValuePair that = (BasicNameValuePair) object;
-            return this.name.equals(that.name)
-                  && equals(this.value, that.value);
-        }
-        return false;
-    }
-
-    private static boolean equals(final Object obj1, final Object obj2) {
-        return obj1 == null ? obj2 == null : obj1.equals(obj2);
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = HASH_SEED;
-        hash = hashCode(hash, this.name);
-        hash = hashCode(hash, this.value);
-        return hash;
-    }
-
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
-
-    private static int hashCode(final int seed, final Object obj) {
-        return hashCode(seed, obj != null ? obj.hashCode() : 0);
-    }
-
-    private static int hashCode(final int seed, final int hashcode) {
-        return seed * HASH_OFFSET + hashcode;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/BinaryUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/BinaryUtils.java
--- ./src/main/java/com/amazonaws/util/BinaryUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/BinaryUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,155 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
- * for applicable license terms and NOTICE.txt for applicable notices.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.ByteArrayInputStream;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * Utilities for encoding and decoding binary data to and from different forms.
- */
-public class BinaryUtils {
-    /**
-     * Converts byte data to a Hex-encoded string in lower case.
-     *
-     * @param data
-     *            data to hex encode.
-     *
-     * @return hex-encoded string.
-     */
-    public static String toHex(byte[] data) {
-        return Base16Lower.encodeAsString(data);
-    }
-
-    /**
-     * Converts a Hex-encoded data string to the original byte data.
-     *
-     * @param hexData
-     *            hex-encoded data to decode.
-     * @return decoded data from the hex string.
-     */
-    public static byte[] fromHex(String hexData) {
-        return Base16Lower.decode(hexData);
-    }
-
-    /**
-     * Converts byte data to a Base64-encoded string.
-     *
-     * @param data
-     *            data to Base64 encode.
-     * @return encoded Base64 string.
-     */
-    public static String toBase64(byte[] data) {
-        return Base64.encodeAsString(data);
-    }
-
-    /**
-     * Converts a Base64-encoded string to the original byte data.
-     *
-     * @param b64Data
-     *            a Base64-encoded string to decode.
-     *
-     * @return bytes decoded from a Base64 string.
-     */
-    public static byte[] fromBase64(String b64Data) {
-        return b64Data == null ? null : Base64.decode(b64Data);
-    }
-
-    /**
-     * Wraps a ByteBuffer in an InputStream. If the input {@code byteBuffer}
-     * is null, returns an empty stream.
-     *
-     * @param byteBuffer The ByteBuffer to wrap.
-     *
-     * @return An InputStream wrapping the ByteBuffer content.
-     */
-    public static ByteArrayInputStream toStream(ByteBuffer byteBuffer) {
-        if (byteBuffer == null) {
-            return new ByteArrayInputStream(new byte[0]);
-        }
-        return new ByteArrayInputStream(copyBytesFrom(byteBuffer));
-    }
-
-    /**
-     * Returns a copy of all the bytes from the given <code>ByteBuffer</code>,
-     * from the beginning to the buffer's limit; or null if the input is null.
-     * <p>
-     * The internal states of the given byte buffer will be restored when this
-     * method completes execution.
-     * <p>
-     * When handling <code>ByteBuffer</code> from user's input, it's typical to
-     * call the {@link #copyBytesFrom(ByteBuffer)} instead of
-     * {@link #copyAllBytesFrom(ByteBuffer)} so as to account for the position
-     * of the input <code>ByteBuffer</code>. The opposite is typically true,
-     * however, when handling <code>ByteBuffer</code> from withint the
-     * unmarshallers of the low-level clients.
-     */
-    public static byte[] copyAllBytesFrom(ByteBuffer bb) {
-        if (bb == null) {
-            return null;
-        }
-
-        if (bb.hasArray()) {
-            return Arrays.copyOfRange(
-                    bb.array(),
-                    bb.arrayOffset(),
-                    bb.arrayOffset() + bb.limit());
-        }
-
-        ByteBuffer copy = bb.asReadOnlyBuffer();
-        copy.rewind();
-
-        byte[] dst = new byte[copy.remaining()];
-        copy.get(dst);
-        return dst;
-    }
-
-    /**
-     * Returns a copy of the bytes from the given <code>ByteBuffer</code>,
-     * ranging from the the buffer's current position to the buffer's limit; or
-     * null if the input is null.
-     * <p>
-     * The internal states of the given byte buffer will be restored when this
-     * method completes execution.
-     * <p>
-     * When handling <code>ByteBuffer</code> from user's input, it's typical to
-     * call the {@link #copyBytesFrom(ByteBuffer)} instead of
-     * {@link #copyAllBytesFrom(ByteBuffer)} so as to account for the position
-     * of the input <code>ByteBuffer</code>. The opposite is typically true,
-     * however, when handling <code>ByteBuffer</code> from withint the
-     * unmarshallers of the low-level clients.
-     */
-    public static byte[] copyBytesFrom(ByteBuffer bb) {
-        if (bb == null) {
-            return null;
-        }
-
-        if (bb.hasArray()) {
-            return Arrays.copyOfRange(
-                    bb.array(),
-                    bb.arrayOffset() + bb.position(),
-                    bb.arrayOffset() + bb.limit());
-        }
-
-        byte[] dst = new byte[bb.remaining()];
-        bb.asReadOnlyBuffer().get(dst);
-        return dst;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/CapacityManager.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CapacityManager.java
--- ./src/main/java/com/amazonaws/util/CapacityManager.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CapacityManager.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * Manages capacity of a finite resource.  Capacity can be acquired and
- * released.
- */
-public class CapacityManager {
-
-    private volatile int availableCapacity;
-    private final int maxCapacity;
-
-    private final Object lock = new Object();
-
-    /**
-     * Creates a CapacityManager.
-     *
-     * @param maxCapacity maximum capacity of this resource.
-     *                    available capacity will initially be set to this value.
-     *                    if a negative value is provided the capacity manager will operate in a no-op
-     *                    passthrough mode in which all acquire calls will return true.
-     */
-    public CapacityManager(final int maxCapacity) {
-        this.maxCapacity = maxCapacity;
-        this.availableCapacity = maxCapacity;
-    }
-
-    /**
-     * Attempts to acquire a single capacity unit.
-     * If acquired, capacity will be consumed from the available pool.
-
-     * @return true if capacity can be acquired, false if not
-     */
-    public boolean acquire() {
-        return acquire(1);
-    }
-
-    /**
-     * Attempts to acquire a given amount of capacity.
-     * If acquired, capacity will be consumed from the available pool.
-     *
-     * @param capacity capacity to acquire
-     * @return true if capacity can be acquired, false if not
-     * @throws IllegalArgumentException if given capacity is negative
-     */
-    public boolean acquire(int capacity) {
-        if (capacity < 0) {
-            throw new IllegalArgumentException("capacity to acquire cannot be negative");
-        }
-
-        if (availableCapacity < 0) {
-            return true;
-        }
-
-        synchronized (lock) {
-            if (availableCapacity - capacity >= 0) {
-                availableCapacity -= capacity;
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Releases a single unit of capacity back to the pool, making it available
-     * to consumers.
-     */
-    public void release() {
-        release(1);
-    }
-
-    /**
-     * Releases a given amount of capacity back to the pool, making it available
-     * to consumers.
-     *
-     * @param capacity capacity to release
-     * @throws IllegalArgumentException if given capacity is negative
-     */
-    public void release(int capacity) {
-        if (capacity < 0) {
-            throw new IllegalArgumentException("capacity to release cannot be negative");
-        }
-
-        // in the common 'good' case where we have our full capacity available we can
-        // short circuit going any further and avoid unnecessary locking.
-        if (availableCapacity >= 0 && availableCapacity != maxCapacity) {
-            synchronized (lock) {
-                availableCapacity = Math.min((availableCapacity + capacity), maxCapacity);
-            }
-        }
-    }
-
-    /**
-     * Returns the currently consumed capacity.
-     *
-     * @return consumed capacity
-     */
-    public int consumedCapacity() {
-        return (availableCapacity < 0) ? 0 : (maxCapacity - availableCapacity);
-    }
-
-    /**
-     * Returns the currently available capacity.
-     *
-     * @return available capacity
-     */
-    public int availableCapacity() {
-        return availableCapacity;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Classes.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Classes.java
--- ./src/main/java/com/amazonaws/util/Classes.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Classes.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,85 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
- * for applicable license terms and NOTICE.txt for applicable notices.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.jar.JarFile;
-
-/**
- * Classes related utilities.
- */
-public enum Classes {
-    ;
-    /**
-     * Returns the class of the immediate subclass of the given parent class for
-     * the given object instance; or null if such immediate subclass cannot be
-     * uniquely identified for the given object instance.
-     * 
-     * @param parentClass
-     *            the parent class. The child class is {@link Object} if and
-     *            only if the parent class is null.
-     * @param instance
-     *            the given object instance
-     */
-    public static Class<?> childClassOf(Class<?> parentClass,
-            Object instance) {
-        if (instance == null || instance == Object.class)
-            return null;
-        if (parentClass != null) {
-            if (parentClass.isInterface()) {
-                // child of an interface class is not injective (ie one-to-one)
-                return null;
-            }
-        }
-        Class<?> childClass = instance.getClass();
-        while (true) {
-            Class<?> parent = childClass.getSuperclass();
-            if (parent == parentClass)
-                return childClass;
-            if (parent == null)
-                return null;
-            childClass = parent;
-        }
-    }
-
-    /**
-     * Returns the jar file from which the given class is loaded; or null
-     * if no such jar file can be located.
-     */
-    public static JarFile jarFileOf(Class<?> klass) {
-        URL url = klass.getResource(
-            "/" + klass.getName().replace('.', '/') + ".class");
-        if (url == null)
-            return null;
-        String s = url.getFile();
-        int beginIndex = s.indexOf("file:") + "file:".length();
-        int endIndex = s.indexOf(".jar!");
-        if (endIndex == -1)
-            return null;
-        endIndex += ".jar".length();
-        String f = s.substring(beginIndex, endIndex);
-        File file = new File(f);
-        try {
-            return file.exists() ? new JarFile(file) : null;
-        } catch (IOException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/ClassLoaderHelper.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ClassLoaderHelper.java
--- ./src/main/java/com/amazonaws/util/ClassLoaderHelper.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ClassLoaderHelper.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,230 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-public enum ClassLoaderHelper {
-    ;
-    /**
-     * Retrieves the resource via the context class loader of the current
-     * thread, and if not found, via the class loaders of the optionally
-     * specified classes in the order of their specification, and if not
-     * found, from the class loader of {@link ClassLoaderHelper} as the last
-     * resort.
-     * 
-     * @param resource
-     *            resource to be loaded
-     * @param classes class loader providers
-     * @return the resource loaded as an URL or null if not found.
-     */
-    public static URL getResource(String resource, Class<?> ... classes) {
-        return getResource(resource, false, classes);
-    }
-
-    /**
-     * If classesFirst is false, retrieves the resource via the context class
-     * loader of the current thread, and if not found, via the class loaders of
-     * the optionally specified classes in the order of their specification, and
-     * if not found, from the class loader of {@link ClassLoaderHelper} as the
-     * last resort.
-     * <p>
-     * If classesFirst is true, retrieves the resource via the optionally
-     * specified classes in the order of their specification, and if not found,
-     * via the context class loader of the current thread, and if not found,
-     * from the class loader of {@link ClassLoaderHelper} as the last resort.
-     * 
-     * @param resource
-     *            resource to be loaded
-     * @param classesFirst
-     *            true if the class loaders of the optionally specified classes
-     *            take precedence over the context class loader of the current
-     *            thread; false if the opposite is true.
-     * @param classes
-     *            class loader providers
-     * @return the resource loaded as an URL or null if not found.
-     */
-    public static URL getResource(String resource, boolean classesFirst,
-            Class<?>... classes) {
-        URL url;
-        if (classesFirst) {
-            url = getResourceViaClasses(resource, classes);
-            if (url == null) {
-                url = getResourceViaContext(resource);
-            }
-        } else {
-            url = getResourceViaContext(resource);
-            if (url == null) {
-                url = getResourceViaClasses(resource, classes);
-            }
-        }
-        return url == null ? ClassLoaderHelper.class.getResource(resource) : url;
-    }
-
-    private static URL getResourceViaClasses(String resource, Class<?>[] classes) {
-        if (classes != null) {
-            for (Class<?> c: classes) {
-                URL url = c.getResource(resource);
-                if (url != null)
-                    return url;
-            }
-        }
-        return null;
-    }
-
-    private static URL getResourceViaContext(String resource) {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        return loader == null ? null : loader.getResource(resource);
-    }
-
-    private static Class<?> loadClassViaClasses(String fqcn, Class<?>[] classes) {
-        if (classes != null) {
-            for (Class<?> c: classes) {
-                ClassLoader loader = c.getClassLoader();
-                if (loader != null) {
-                    try {
-                        return loader.loadClass(fqcn);
-                    } catch (ClassNotFoundException e) {
-                        // move on to try the next class loader
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    private static Class<?> loadClassViaContext(String fqcn) {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        try {
-            return loader == null ? null : loader.loadClass(fqcn);
-        } catch (ClassNotFoundException e) {
-        }
-        return null;
-    }
-
-    /**
-     * Loads the class via the optionally specified classes in the order of
-     * their specification, and if not found, via the context class loader of
-     * the current thread, and if not found, from the caller class loader as the
-     * last resort.
-     * 
-     * @param fqcn
-     *            fully qualified class name of the target class to be loaded
-     * @param classes
-     *            class loader providers
-     * @return the class loaded; never null
-     * 
-     * @throws ClassNotFoundException
-     *             if failed to load the class
-     */
-    public static Class<?> loadClass(String fqcn, Class<?>... classes)
-            throws ClassNotFoundException {
-        return loadClass(fqcn, true, classes);
-    }
-
-    /**
-     * If classesFirst is false, loads the class via the context class
-     * loader of the current thread, and if not found, via the class loaders of
-     * the optionally specified classes in the order of their specification, and
-     * if not found, from the caller class loader as the
-     * last resort.
-     * <p>
-     * If classesFirst is true, loads the class via the optionally
-     * specified classes in the order of their specification, and if not found,
-     * via the context class loader of the current thread, and if not found,
-     * from the caller class loader as the last resort.
-     * 
-     * @param fqcn
-     *            fully qualified class name of the target class to be loaded
-     * @param classesFirst
-     *            true if the class loaders of the optionally specified classes
-     *            take precedence over the context class loader of the current
-     *            thread; false if the opposite is true.
-     * @param classes
-     *            class loader providers
-     * @return the class loaded; never null
-     * 
-     * @throws ClassNotFoundException if failed to load the class
-     */
-    public static Class<?> loadClass(String fqcn, boolean classesFirst,
-            Class<?>... classes) throws ClassNotFoundException {
-        Class<?> target = null;
-        if (classesFirst) {
-            target = loadClassViaClasses(fqcn, classes);
-            if (target == null) {
-                target = loadClassViaContext(fqcn);
-            }
-        } else {
-            target = loadClassViaContext(fqcn);
-            if (target == null) {
-                target = loadClassViaClasses(fqcn, classes);
-            }
-        }
-        return target == null ? Class.forName(fqcn) : target;
-    }
-
-    /**
-     * Retrieves the resource as an input stream via
-     * the context class loader of the current thread, and if not found, via the
-     * class loaders of the optionally specified classes in the order of their
-     * specification, and if not found, from the class loader of
-     * {@link ClassLoaderHelper} as the last resort.
-     * 
-     * @param resource
-     *            resource to be loaded
-     * @param classes
-     *            class loader providers
-     * @return the resource loaded as an input stream or null if not found.
-     */
-    public static InputStream getResourceAsStream(String resource,
-            Class<?>... classes) {
-        return getResourceAsStream(resource, false, classes);
-    }
-
-    /**
-     * If classesFirst is false, retrieves the resource as an input stream via
-     * the context class loader of the current thread, and if not found, via the
-     * class loaders of the optionally specified classes in the order of their
-     * specification, and if not found, from the class loader of
-     * {@link ClassLoaderHelper} as the last resort.
-     * <p>
-     * If classesFirst is true, retrieves the resource as an input stream via
-     * the optionally specified classes in the order of their specification, and
-     * if not found, via the context class loader of the current thread, and if
-     * not found, from the class loader of {@link ClassLoaderHelper} as the last
-     * resort.
-     * 
-     * @param resource
-     *            resource to be loaded
-     * @param classesFirst
-     *            true if the class loaders of the optionally specified classes
-     *            take precedence over the context class loader of the current
-     *            thread; false if the opposite is true.
-     * @param classes
-     *            class loader providers
-     * @return the resource loaded as an input stream or null if not found.
-     */
-    public static InputStream getResourceAsStream(String resource,
-            boolean classesFirst, Class<?>... classes) {
-        URL url = getResource(resource, classesFirst, classes);
-        try {
-            return url != null ? url.openStream() : null;
-        } catch (IOException e) {
-            return null;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Codec.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Codec.java
--- ./src/main/java/com/amazonaws/util/Codec.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Codec.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * Codec SPI
- * 
- * @author Hanson Char
- */
-interface Codec {
-    public byte[] encode(byte[] src);
-    public byte[] decode(byte[] src, final int length); 
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/util/CodecUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CodecUtils.java
--- ./src/main/java/com/amazonaws/util/CodecUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CodecUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,111 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * Codec internal utilities
- * 
- * @author Hanson Char
- */
-public enum CodecUtils {
-    ;
-    /**
-     * Transforms the given string into the given destination byte array
-     * truncating each character into a byte and skipping carriage returns and
-     * line feeds if any.
-     * <p>
-     * dmurray: "It so happens that we're currently only calling this method
-     * with src.length == dest.length, in which case it works, but we could
-     * theoretically get away with passing a smaller dest if we knew ahead of
-     * time that src contained some number of spaces. In that case it looks like
-     * this implementation would truncate the result."
-     * <p>
-     * hchar:
-     * "Yes, but the truncation is the intentional behavior of this internal 
-     * routine in that case."
-     * 
-     * @param singleOctets
-     *            non-null string containing only single octet characters
-     * @param dest
-     *            destination byte array
-     * 
-     * @return the actual length of the destination byte array holding data
-     * @throws IllegalArgumentException
-     *             if the input string contains any multi-octet character
-     */
-    static int sanitize(final String singleOctets, byte[] dest) {
-        final int capacity = dest.length;
-        final char[] src = singleOctets.toCharArray();
-        int limit=0;
-
-        for (int i=0; i < capacity; i++) {
-            final char c = src[i];
-            
-            if (c == '\r' || c == '\n' || c == ' ')
-                continue;
-            if (c > Byte.MAX_VALUE)
-                throw new IllegalArgumentException("Invalid character found at position " + i + " for " + singleOctets);
-            dest[limit++] = (byte)c;
-        }
-        return limit;
-    }
-    
-    /**
-     * Returns a byte array representing the given string,
-     * truncating each character into a byte directly.
-     * 
-     * @throws IllegalArgumentException if the input string contains any multi-octet character
-     */
-    public static byte[] toBytesDirect(final String singleOctets) {
-        final char[] src = singleOctets.toCharArray();
-        final byte[] dest = new byte[src.length];
-        
-        for (int i=0; i < dest.length; i++) {
-            final char c = src[i];
-            
-            if (c > Byte.MAX_VALUE)
-                throw new IllegalArgumentException("Invalid character found at position " + i + " for " + singleOctets);
-            dest[i] = (byte)c;
-        }
-        return dest;
-    }
-
-    /**
-     * Returns a string representing the given byte array,
-     * treating each byte as a single octet character.
-     */
-    public static String toStringDirect(final byte[] bytes) {
-        final char[] dest = new char[bytes.length];
-        int i=0;
-        
-        for (byte b: bytes)
-            dest[i++] = (char)b;
-        
-        return new String(dest);
-    }
-    
-    /** 
-     * Sanity check the last decoded position is a possible value.
-     * 
-     * @throws IllegalArgumentException if the given decoded position is
-     * not a possible value produced via the respective encoding 
-     */
-    static void sanityCheckLastPos(int pos, int mask) {
-        if ((pos & mask) != 0) {
-            throw new IllegalArgumentException
-                ("Invalid last non-pad character detected");
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/util/ComparableUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ComparableUtils.java
--- ./src/main/java/com/amazonaws/util/ComparableUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ComparableUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,42 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-public class ComparableUtils {
-
-    /**
-     * Does a safe comparison of two {@link Comparable} objects accounting for nulls
-     * 
-     * @param d1
-     *            First object
-     * @param d2
-     *            Second object
-     * @return A positive number if the object double is larger, a negative number if the second
-     *         object is larger, or 0 if they are equal. Null is considered less than any non-null
-     *         value
-     */
-    public static <T> int safeCompare(Comparable<T> d1, T d2) {
-        if (d1 != null && d2 != null) {
-            return d1.compareTo(d2);
-        } else if (d1 == null && d2 != null) {
-            return -1;
-        } else if (d1 != null && d2 == null) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/CountingInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CountingInputStream.java
--- ./src/main/java/com/amazonaws/util/CountingInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CountingInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,54 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * Simple input stream wrapper utility to count the bytes read from a stream.
- */
-public class CountingInputStream extends SdkFilterInputStream {
-    private long byteCount = 0;
-
-    public CountingInputStream(InputStream in) {
-        super(in);
-    }
-
-    /**
-     * Returns the number of bytes read from this stream so far.
-     *
-     * @return the number of bytes read from this stream so far.
-     */
-    public long getByteCount() {
-        return byteCount;
-    }
-
-    @Override
-    public int read() throws IOException {
-        int tmp = super.read();
-        byteCount += tmp >= 0 ? 1 : 0;
-        return tmp;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        int tmp = super.read(b, off, len);
-        byteCount += tmp >= 0 ? tmp : 0;
-        return tmp;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/CRC32ChecksumCalculatingInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CRC32ChecksumCalculatingInputStream.java
--- ./src/main/java/com/amazonaws/util/CRC32ChecksumCalculatingInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CRC32ChecksumCalculatingInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,78 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.CRC32;
-
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * Simple InputStream wrapper that examines the wrapped stream's contents as
- * they are read and calculates and CRC32 checksum.
- */
-public class CRC32ChecksumCalculatingInputStream extends SdkFilterInputStream {
-
-    /** The CRC32 being calculated by this input stream */
-    private CRC32 crc32;
-
-    public CRC32ChecksumCalculatingInputStream(InputStream in) {
-        super(in);
-        crc32 = new CRC32();
-    }
-
-    public long getCRC32Checksum() {
-        return crc32.getValue();
-    }
-
-    /**
-     * Resets the wrapped input stream and the CRC32 computation.
-     *
-     * @see java.io.InputStream#reset()
-     */
-    @Override
-    public synchronized void reset() throws IOException {
-        abortIfNeeded();
-        crc32.reset();
-        in.reset();
-    }
-
-    /**
-     * @see java.io.InputStream#read()
-     */
-    @Override
-    public int read() throws IOException {
-        abortIfNeeded();
-        int ch = in.read();
-        if (ch != -1) {
-            crc32.update(ch);
-        }
-        return ch;
-    }
-
-    /**
-     * @see java.io.InputStream#read(byte[], int, int)
-     */
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        abortIfNeeded();
-        int result = in.read(b, off, len);
-        if (result != -1) {
-            crc32.update(b, off, result);
-        }
-        return result;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/CredentialUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CredentialUtils.java
--- ./src/main/java/com/amazonaws/util/CredentialUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/CredentialUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is
- * distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either
- * express or implied. See the License for the specific language
- * governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.RequestConfig;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.internal.StaticCredentialsProvider;
-
-public class CredentialUtils {
-
-    /**
-     *  Returns the credentials provider that will be used to fetch the
-     *  credentials when signing the request. Request specific credentials
-     *  takes precedence over the credentials/credentials provider set in the
-     *  client.
-     */
-    public static AWSCredentialsProvider getCredentialsProvider(
-            AmazonWebServiceRequest req,
-            AWSCredentialsProvider base) {
-
-        if (req != null && req.getRequestCredentialsProvider() != null) {
-            return req.getRequestCredentialsProvider();
-        }
-        return base;
-    }
-
-    public static AWSCredentialsProvider getCredentialsProvider(
-            RequestConfig requestConfig,
-            AWSCredentialsProvider base) {
-
-        if (requestConfig.getCredentialsProvider() != null) {
-            return requestConfig.getCredentialsProvider();
-        }
-        return base;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/EncodingSchemeEnum.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EncodingSchemeEnum.java
--- ./src/main/java/com/amazonaws/util/EncodingSchemeEnum.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EncodingSchemeEnum.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * Currently provided encoding schemes "out of the box".
- *  
- * @author Hanson Char
- * 
- * See http://www.ietf.org/rfc/rfc4648.txt
- */
-public enum EncodingSchemeEnum implements EncodingScheme {
-    BASE16 {
-        @Override public String encodeAsString(byte[] bytes) { 
-            return Base16.encodeAsString(bytes); 
-        }
-        @Override public byte[] decode(String encoded) { 
-            return Base16.decode(encoded); 
-        }
-    },
-    BASE32 {
-        @Override public String encodeAsString(byte[] bytes) { 
-            return Base32.encodeAsString(bytes); 
-        }
-        @Override public byte[] decode(String encoded) { 
-            return Base32.decode(encoded); 
-        }
-    },
-    BASE64 {
-        @Override public String encodeAsString(byte[] bytes) { 
-            return Base64.encodeAsString(bytes); 
-        }
-        @Override public byte[] decode(String encoded) { 
-            return Base64.decode(encoded); 
-        }
-    },
-    ;
-
-    @Override public abstract String encodeAsString(byte[] bytes);
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/EncodingScheme.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EncodingScheme.java
--- ./src/main/java/com/amazonaws/util/EncodingScheme.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/EncodingScheme.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,25 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * Encoding scheme.
- *  
- * @author Hanson Char
- */
-public interface EncodingScheme {
-    public String encodeAsString(byte[] bytes);
-    public byte[] decode(String encoded);
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/FakeIOException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/FakeIOException.java
--- ./src/main/java/com/amazonaws/util/FakeIOException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/FakeIOException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.util;
-
-import java.io.IOException;
-
-/**
- * Used for simulating an IOException for test purposes.
- */
-public class FakeIOException extends IOException {
-    private static final long serialVersionUID = 1L;
-
-    public FakeIOException(String message) {
-        super(message);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/util/HttpClientWrappingInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/HttpClientWrappingInputStream.java
--- ./src/main/java/com/amazonaws/util/HttpClientWrappingInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/HttpClientWrappingInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.http.client.HttpClient;
-
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * An {@code InputStream} that closes the associated {@code HttpClient}
- * when the stream is closed.
- */
-class HttpClientWrappingInputStream extends SdkFilterInputStream {
-
-    private final HttpClient client;
-
-    /**
-     * @param client the {@code HttpClient} to wrap
-     * @param stream the {@code InputStream} to wrap
-     */
-    public HttpClientWrappingInputStream(
-            final HttpClient client,
-            final InputStream stream) {
-
-        super(stream);
-        this.client = client;
-    }
-
-    @Override
-    @SuppressWarnings("deprecation")
-    public void close() throws IOException {
-        try {
-            super.close();
-        } finally {
-            client.getConnectionManager().shutdown();
-        }
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/util/IdempotentUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/IdempotentUtils.java
--- ./src/main/java/com/amazonaws/util/IdempotentUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/IdempotentUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2016. Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.util;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.annotation.SdkTestInternalApi;
-import com.amazonaws.protocol.DefaultValueSupplier;
-
-import java.util.UUID;
-
-/**
- * Utility class to manage idempotency token
- */
-@SdkProtectedApi
-public final class IdempotentUtils {
-
-    private static DefaultValueSupplier<String> generator = new DefaultValueSupplier<String>() {
-        @Override
-        public String get() {
-            return UUID.randomUUID().toString();
-        }
-    };
-
-    /**
-     * @deprecated By {@link #getGenerator()}
-     */
-    @Deprecated
-    @SdkProtectedApi
-    public static String resolveString(String token) {
-        return token != null ? token : generator.get();
-    }
-
-    @SdkProtectedApi
-    public static DefaultValueSupplier<String> getGenerator() {
-        return generator;
-    }
-
-
-    @SdkTestInternalApi
-    public static void setGenerator(DefaultValueSupplier<String> newGenerator) {
-        generator = newGenerator;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/ImmutableMapParameter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ImmutableMapParameter.java
--- ./src/main/java/com/amazonaws/util/ImmutableMapParameter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ImmutableMapParameter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,305 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An immutable map that could be built by convenient constructors.
- * <p>
- * Example of using map Builder:
- * 
- * <pre>
- * {
- *     &#064;code
- *     Map&lt;String, AttibuteValue&gt; item = new ImmutableMapParameter.Builder&lt;String, AttibuteValue&gt;()
- *             .put(&quot;one&quot;, new AttibuteValue(&quot;1&quot;))
- *             .put(&quot;two&quot;, new AttibuteValue(&quot;2&quot;))
- *             .put(&quot;three&quot;, new AttibuteValue(&quot;3&quot;)).build();
- * }
- * </pre>
- * 
- * For <i>small</i> immutable maps (up to five entries), the
- * {@code ImmutableMapParamter.of()} methods are preferred:
- * 
- * <pre>
- * {@code
- *   Map<String, AttibuteValue> item =
- *       ImmutableMapParameter
- *           .of("one", new AttributeValue("1"), 
- *               "two", new AttributeValue("2"),
- *               "three", new AttributeValue("3"), 
- * }
- * </pre>
- * 
- * @param <K>
- *            Class of the key for the map.
- * @param <V>
- *            Class of the value for the map.
- */
-public class ImmutableMapParameter<K, V> implements Map<K, V> {
-
-    private static final String UNMODIFIABLE_MESSAGE = "This is an immutable map.";
-    private static final String DUPLICATED_KEY_MESSAGE = "Duplicate keys are provided.";
-
-    private final Map<K, V> map;
-
-    private ImmutableMapParameter(Map<K, V> map) {
-        this.map = map;
-    }
-
-    /**
-     * Returns a new MapParameterBuilder instance.
-     */
-    public static <K, V> Builder<K, V> builder() {
-        return new Builder<K, V>();
-    }
-
-    /**
-     * Returns an ImmutableMapParameter instance containing a single entry.
-     * 
-     * @param k0
-     *            Key of the single entry.
-     * @param v0
-     *            Value of the single entry.
-     */
-    public static <K, V> ImmutableMapParameter<K, V> of(K k0, V v0) {
-        Map<K, V> map = Collections.singletonMap(k0, v0);
-        return new ImmutableMapParameter<K, V>(map);
-    }
-
-    /**
-     * Returns an ImmutableMapParameter instance containing two entries.
-     * 
-     * @param k0
-     *            Key of the first entry.
-     * @param v0
-     *            Value of the first entry.
-     * @param k1
-     *            Key of the second entry.
-     * @param v1
-     *            Value of the second entry.
-     */
-    public static <K, V> ImmutableMapParameter<K, V> of(K k0, V v0, K k1, V v1) {
-        Map<K, V> map = new HashMap<K, V>();
-        putAndWarnDuplicateKeys(map, k0, v0);
-        putAndWarnDuplicateKeys(map, k1, v1);
-        return new ImmutableMapParameter<K, V>(map);
-    }
-
-    /**
-     * Returns an ImmutableMapParameter instance containing three entries.
-     * 
-     * @param k0
-     *            Key of the first entry.
-     * @param v0
-     *            Value of the first entry.
-     * @param k1
-     *            Key of the second entry.
-     * @param v1
-     *            Value of the second entry.
-     * @param k2
-     *            Key of the third entry.
-     * @param v2
-     *            Value of the third entry.
-     */
-    public static <K, V> ImmutableMapParameter<K, V> of(K k0, V v0, K k1, V v1,
-            K k2, V v2) {
-        Map<K, V> map = new HashMap<K, V>();
-        putAndWarnDuplicateKeys(map, k0, v0);
-        putAndWarnDuplicateKeys(map, k1, v1);
-        putAndWarnDuplicateKeys(map, k2, v2);
-        return new ImmutableMapParameter<K, V>(map);
-    }
-
-    /**
-     * Returns an ImmutableMapParameter instance containing four entries.
-     * 
-     * @param k0
-     *            Key of the first entry.
-     * @param v0
-     *            Value of the first entry.
-     * @param k1
-     *            Key of the second entry.
-     * @param v1
-     *            Value of the second entry.
-     * @param k2
-     *            Key of the third entry.
-     * @param v2
-     *            Value of the third entry.
-     * @param k3
-     *            Key of the fourth entry.
-     * @param v3
-     *            Value of the fourth entry.
-     */
-    public static <K, V> ImmutableMapParameter<K, V> of(K k0, V v0, K k1, V v1,
-            K k2, V v2, K k3, V v3) {
-        Map<K, V> map = new HashMap<K, V>();
-        putAndWarnDuplicateKeys(map, k0, v0);
-        putAndWarnDuplicateKeys(map, k1, v1);
-        putAndWarnDuplicateKeys(map, k2, v2);
-        putAndWarnDuplicateKeys(map, k3, v3);
-        return new ImmutableMapParameter<K, V>(map);
-    }
-
-    /**
-     * Returns an ImmutableMapParameter instance containing five entries.
-     * 
-     * @param k0
-     *            Key of the first entry.
-     * @param v0
-     *            Value of the first entry.
-     * @param k1
-     *            Key of the second entry.
-     * @param v1
-     *            Value of the second entry.
-     * @param k2
-     *            Key of the third entry.
-     * @param v2
-     *            Value of the third entry.
-     * @param k3
-     *            Key of the fourth entry.
-     * @param v3
-     *            Value of the fourth entry.
-     * @param k4
-     *            Key of the fifth entry.
-     * @param v4
-     *            Value of the fifth entry.
-     */
-    public static <K, V> ImmutableMapParameter<K, V> of(K k0, V v0, K k1, V v1,
-            K k2, V v2, K k3, V v3, K k4, V v4) {
-        Map<K, V> map = new HashMap<K, V>();
-        putAndWarnDuplicateKeys(map, k0, v0);
-        putAndWarnDuplicateKeys(map, k1, v1);
-        putAndWarnDuplicateKeys(map, k2, v2);
-        putAndWarnDuplicateKeys(map, k3, v3);
-        putAndWarnDuplicateKeys(map, k4, v4);
-        return new ImmutableMapParameter<K, V>(map);
-    }
-
-    /** Inherited methods **/
-
-    public boolean containsKey(Object key) {
-        return map.containsKey(key);
-    }
-
-    public boolean containsValue(Object value) {
-        return map.containsValue(value);
-    }
-
-    public Set<Entry<K, V>> entrySet() {
-        return map.entrySet();
-    }
-
-    public V get(Object key) {
-        return map.get(key);
-    }
-
-    public boolean isEmpty() {
-        return map.isEmpty();
-    }
-
-    public Set<K> keySet() {
-        return map.keySet();
-    }
-
-    public int size() {
-        return map.size();
-    }
-
-    public Collection<V> values() {
-        return map.values();
-    }
-
-    /** Unsupported methods **/
-
-    public void clear() {
-        throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE);
-    }
-
-    public V put(K key, V value) {
-        throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE);
-    }
-
-    public void putAll(Map<? extends K, ? extends V> map) {
-        throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE);
-    }
-
-    public V remove(Object key) {
-        throw new UnsupportedOperationException(UNMODIFIABLE_MESSAGE);
-    }
-
-    private static <K, V> void putAndWarnDuplicateKeys(Map<K, V> map, K key,
-            V value) {
-        if (map.containsKey(key))
-            throw new IllegalArgumentException(DUPLICATED_KEY_MESSAGE);
-        map.put(key, value);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        return map.equals(o);
-    }
-
-    @Override
-    public int hashCode() {
-        return map.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return map.toString();
-    }
-
-    /**
-     * A convenient builder for creating ImmutableMapParameter instances.
-     */
-    public static class Builder<K, V> {
-
-        private final Map<K, V> entries;
-
-        public Builder() {
-            this.entries = new HashMap<K, V>();
-        }
-
-        /**
-         * Add a key-value pair into the built map. The method will throw
-         * IllegalArgumentException immediately when duplicate keys are
-         * provided.
-         * 
-         * @return Returns a reference to this object so that method calls can
-         *         be chained together.
-         */
-        public Builder<K, V> put(K key, V value) {
-            putAndWarnDuplicateKeys(entries, key, value);
-            return this;
-        }
-
-        /**
-         * Generates and returns a new ImmutableMapParameter instance which
-         * contains all the entries added into the Builder by {@code put()}
-         * method.
-         */
-        public ImmutableMapParameter<K, V> build() {
-            HashMap<K, V> builtMap = new HashMap<K, V>();
-            builtMap.putAll(entries);
-            return new ImmutableMapParameter<K, V>(builtMap);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/IOUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/IOUtils.java
--- ./src/main/java/com/amazonaws/util/IOUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/IOUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,136 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.internal.Releasable;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * Utilities for IO operations.
- */
-public enum IOUtils {
-    ;
-    private static final int BUFFER_SIZE = 1024 * 4;
-    private static final Log defaultLog = LogFactory.getLog(IOUtils.class);
-
-    /**
-     * Reads and returns the rest of the given input stream as a byte array.
-     * Caller is responsible for closing the given input stream.
-     */
-    public static byte[] toByteArray(InputStream is) throws IOException {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        try {
-            byte[] b = new byte[BUFFER_SIZE];
-            int n = 0;
-            while ((n = is.read(b)) != -1) {
-                output.write(b, 0, n);
-            }
-            return output.toByteArray();
-        } finally {
-            output.close();
-        }
-    }
-
-    /**
-     * Reads and returns the rest of the given input stream as a string.
-     * Caller is responsible for closing the given input stream.
-     */
-    public static String toString(InputStream is) throws IOException {
-        return new String(toByteArray(is), StringUtils.UTF8);
-    }
-
-    /**
-     * Closes the given Closeable quietly.
-     *
-     * @param is  the given closeable
-     * @param log logger used to log any failure should the close fail
-     */
-    public static void closeQuietly(Closeable is, Log log) {
-        if (is != null) {
-            try {
-                is.close();
-            } catch (IOException ex) {
-                Log logger = log == null ? defaultLog : log;
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Ignore failure in closing the Closeable", ex);
-                }
-            }
-        }
-    }
-
-    /**
-     * Releases the given {@link Closeable} especially if it was an instance of
-     * {@link Releasable}.
-     * <p>
-     * For example, the creation of a <code>ResettableInputStream</code> would entail
-     * physically opening a file. If the opened file is meant to be closed only
-     * (in a finally block) by the very same code block that created it, then it
-     * is necessary that the release method must not be called while the
-     * execution is made in other stack frames.
-     *
-     * In such case, as other stack frames may inadvertently or indirectly call
-     * the close method of the stream, the creator of the stream would need to
-     * explicitly disable the accidental closing via
-     * <code>ResettableInputStream#disableClose()</code>, so that the release method
-     * becomes the only way to truly close the opened file.
-     */
-    public static void release(Closeable is, Log log) {
-        closeQuietly(is, log);
-        if (is instanceof Releasable) {
-            Releasable r = (Releasable) is;
-            r.release();
-        }
-    }
-
-    /**
-     * Copies all bytes from the given input stream to the given output stream.
-     * Caller is responsible for closing the streams.
-     *
-     * @throws IOException if there is any IO exception during read or write.
-     */
-    public static long copy(InputStream in, OutputStream out)
-            throws IOException {
-        byte[] buf = new byte[BUFFER_SIZE];
-        long count = 0;
-        int n = 0;
-        while ((n = in.read(buf)) > -1) {
-            out.write(buf, 0, n);
-            count += n;
-        }
-        return count;
-    }
-
-    /**
-     * Read all remaining data in the stream.
-     *
-     * @param in InputStream to read.
-     */
-    public static void drainInputStream(InputStream in) {
-        try {
-            while (in.read() != -1) {
-                // Do nothing.
-            }
-        } catch (IOException ignored) {
-            // Stream may be self closed by HTTP client so we ignore any failures.
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/JavaVersionParser.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/JavaVersionParser.java
--- ./src/main/java/com/amazonaws/util/JavaVersionParser.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/JavaVersionParser.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,268 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @see http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
- */
-public class JavaVersionParser {
-
-    public static final String JAVA_VERSION_PROPERTY = "java.version";
-
-    private static String MAJOR_VERSION_FAMILY_PATTERN = "\\d+";
-    private static String MAJOR_VERSION_PATTERN = "\\d+";
-    private static String MAINTENANCE_NUMBER_PATTERN = "\\d+";
-    private static String UPDATE_NUMBER_PATTERN = "\\d+";
-
-    private static Pattern VERSION_REGEX = Pattern.compile(String.format("(%s)\\.(%s)\\.(%s)(?:_(%s))?.*",
-            MAJOR_VERSION_FAMILY_PATTERN, MAJOR_VERSION_PATTERN, MAINTENANCE_NUMBER_PATTERN, UPDATE_NUMBER_PATTERN));
-
-    private static final JavaVersion currentJavaVersion = parseJavaVersion(System.getProperty(JAVA_VERSION_PROPERTY));
-
-    private JavaVersionParser() {
-    }
-
-    /**
-     * @return The {@link JavaVersion} of this JVM.
-     */
-    public static JavaVersion getCurrentJavaVersion() {
-        return currentJavaVersion;
-    }
-
-    public static JavaVersion parseJavaVersion(final String fullVersionString) {
-        if (!StringUtils.isNullOrEmpty(fullVersionString)) {
-            final Matcher matcher = VERSION_REGEX.matcher(fullVersionString);
-            if (matcher.matches()) {
-                final Integer majorVersionFamily = NumberUtils.tryParseInt(matcher.group(1));
-                final Integer majorVersion = NumberUtils.tryParseInt(matcher.group(2));
-                final Integer maintenanceNumber = NumberUtils.tryParseInt(matcher.group(3));
-                final Integer updateNumber = NumberUtils.tryParseInt(matcher.group(4));
-                return new JavaVersion(majorVersionFamily, majorVersion, maintenanceNumber, updateNumber);
-            }
-        }
-        return JavaVersion.UNKNOWN;
-    }
-
-    /**
-     * Struct like class representing a specific version of Java. Contains the major and minor
-     * version identifiers and a descriptive enum identifying which major version this JVM belongs
-     * to if we are able to identify it
-     */
-    public static final class JavaVersion implements Comparable<JavaVersion> {
-
-        public static final JavaVersionParser.JavaVersion UNKNOWN = new JavaVersionParser.JavaVersion(null, null, null,
-                null);
-
-        private final Integer[] tokenizedVersion;
-        private final Integer majorVersionFamily;
-        private final Integer majorVersion;
-        private final Integer maintenanceNumber;
-        private final Integer updateNumber;
-        private final KnownJavaVersions knownVersion;
-
-        public JavaVersion(final Integer majorVersionFamily, final Integer majorVersion,
-                final Integer maintenanceNumber, final Integer updateNumber) {
-            this.majorVersionFamily = majorVersionFamily;
-            this.majorVersion = majorVersion;
-            this.maintenanceNumber = maintenanceNumber;
-            this.updateNumber = updateNumber;
-            this.knownVersion = KnownJavaVersions.fromMajorVersion(majorVersionFamily, majorVersion);
-            this.tokenizedVersion = this.getTokenizedVersion();
-        }
-
-        private Integer[] getTokenizedVersion() {
-            return new Integer[] { this.majorVersionFamily, this.majorVersion, this.maintenanceNumber,
-                    this.updateNumber };
-        }
-
-        /**
-         * @return Major version family if available. I.E. if the major version family string is
-         *         '1.7.0_60' then the major version family will be 1
-         */
-        public Integer getMajorVersionFamily() {
-            return this.majorVersionFamily;
-        }
-
-        /**
-         * @return Major version ordinal if available. Examples include '6', '7', '8'
-         */
-        public Integer getMajorVersion() {
-            return this.majorVersion;
-        }
-
-        /**
-         * @return Major version string if available. Examples include '1.6', '1.7', '1.8'
-         */
-        public String getMajorVersionString() {
-            return String.format("%d.%d", this.majorVersionFamily, this.majorVersion);
-        }
-
-        /**
-         * @return Maintenance number of Java version. If the version is '1.6.1_20' then '1' is the
-         *         maintenance number
-         */
-        public Integer getMaintenanceNumber() {
-            return this.maintenanceNumber;
-        }
-
-        /**
-         * @return Update number of Java version. If the version is '1.6.1_20' then '20' is the
-         *         update number
-         */
-        public Integer getUpdateNumber() {
-            return this.updateNumber;
-        }
-
-        /**
-         * @return {@link KnownJavaVersions} representing the major version of the Java version if
-         *         it's identifiable
-         */
-        public KnownJavaVersions getKnownVersion() {
-            return this.knownVersion;
-        }
-
-        @Override
-        public int compareTo(final JavaVersion other) {
-            for (int i = 0; i < this.tokenizedVersion.length; i++) {
-                final int tokenComparison = ComparableUtils.safeCompare(this.tokenizedVersion[i],
-                        other.tokenizedVersion[i]);
-                // If one token is larger return the comparison otherwise proceed to next token
-                if (tokenComparison != 0) {
-                    return tokenComparison;
-                }
-            }
-            return 0;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = (prime * result) + ((this.knownVersion == null) ? 0 : this.knownVersion.hashCode());
-            result = (prime * result) + ((this.maintenanceNumber == null) ? 0 : this.maintenanceNumber.hashCode());
-            result = (prime * result) + ((this.majorVersion == null) ? 0 : this.majorVersion.hashCode());
-            result = (prime * result) + ((this.majorVersionFamily == null) ? 0 : this.majorVersionFamily.hashCode());
-            result = (prime * result) + Arrays.hashCode(this.tokenizedVersion);
-            result = (prime * result) + ((this.updateNumber == null) ? 0 : this.updateNumber.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(final Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (this.getClass() != obj.getClass()) {
-                return false;
-            }
-            final JavaVersion other = (JavaVersion) obj;
-            if (this.knownVersion != other.knownVersion) {
-                return false;
-            }
-            if (this.maintenanceNumber == null) {
-                if (other.maintenanceNumber != null) {
-                    return false;
-                }
-            } else if (!this.maintenanceNumber.equals(other.maintenanceNumber)) {
-                return false;
-            }
-            if (this.majorVersion == null) {
-                if (other.majorVersion != null) {
-                    return false;
-                }
-            } else if (!this.majorVersion.equals(other.majorVersion)) {
-                return false;
-            }
-            if (this.majorVersionFamily == null) {
-                if (other.majorVersionFamily != null) {
-                    return false;
-                }
-            } else if (!this.majorVersionFamily.equals(other.majorVersionFamily)) {
-                return false;
-            }
-            if (!Arrays.equals(this.tokenizedVersion, other.tokenizedVersion)) {
-                return false;
-            }
-            if (this.updateNumber == null) {
-                if (other.updateNumber != null) {
-                    return false;
-                }
-            } else if (!this.updateNumber.equals(other.updateNumber)) {
-                return false;
-            }
-            return true;
-        }
-
-    }
-
-    /**
-     * Enum representing all the Java versions we know about and a special enum value
-     * {@link KnownJavaVersions#UNKNOWN} for ones we don't yet know about
-     */
-    public enum KnownJavaVersions {
-        JAVA_6(1, 6),
-        JAVA_7(1, 7),
-        JAVA_8(1, 8),
-        JAVA_9(1, 9),
-        UNKNOWN(0, -1);
-
-        private Integer knownMajorVersionFamily;
-        private Integer knownMajorVersion;
-
-        private KnownJavaVersions(final int majorVersionFamily, final int majorVersion) {
-            this.knownMajorVersionFamily = majorVersionFamily;
-            this.knownMajorVersion = Integer.valueOf(majorVersion);
-        }
-
-        /**
-         * Tries to determine a known version from the parsed major version components
-         *
-         * @param majorVersionFamily
-         *            Major version family of the JVM. Currently only 1 is known (i.e. '1.7')
-         * @param majorVersion
-         *            Major version of JVM (6, 7, 8, etc)
-         * @return A {@link KnownJavaVersions} or {@link KnownJavaVersions#UNKNOWN} if unable to
-         *         determine
-         */
-        public static KnownJavaVersions fromMajorVersion(final Integer majorVersionFamily, final Integer majorVersion) {
-            for (final KnownJavaVersions version : KnownJavaVersions.values()) {
-                if (version.isMajorVersion(majorVersionFamily, majorVersion)) {
-                    return version;
-                }
-            }
-            return UNKNOWN;
-        }
-
-        /**
-         * @param majorVersionFamily
-         *            Major version family of the JVM. Currently only 1 is known (i.e. '1.7')
-         * @param majorVersion
-         *            Major version of JVM (6, 7, 8, etc)
-         * @return True if the major version is applicable to this Java Version
-         */
-        private boolean isMajorVersion(final Integer majorVersionFamily, final Integer majorVersion) {
-            return this.knownMajorVersionFamily.equals(majorVersionFamily)
-                    && this.knownMajorVersion.equals(majorVersion);
-        }
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/JodaTime.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/JodaTime.java
--- ./src/main/java/com/amazonaws/util/JodaTime.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/JodaTime.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,210 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.SimpleTimeZone;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-
-import com.amazonaws.log.InternalLogFactory;
-
-/**
- * Utilities for accessing joda-time.
- */
-public enum JodaTime {
-    ;
-    private static final boolean expectedBehavior = checkExpectedBehavior();
-
-    /**
-     * Returns the current version of joda-time used during runtime; or null
-     * if it cannot be determined.
-     */
-    public static String getVersion() {
-        return LazyHolder.version;
-    }
-
-    /**
-     * Returns true if the current version of joda-time used during runtime
-     * behaves as expected by the Java SDK; false otherwise.
-     */
-    public static boolean hasExpectedBehavior() {
-        return expectedBehavior;
-    }
-
-    /**
-     * A lazy holder class for retrieving the version of joda-time used during
-     * runtime from the jar file discovered on the classpath.
-     */
-    private static class LazyHolder {
-        static final String version = getVersion();
-
-        private static String getVersion() {
-            try {
-                JarFile jf = Classes.jarFileOf(DateTimeZone.class);
-                if (jf == null)
-                    return null;
-                Manifest mf = jf.getManifest();
-                Attributes attrs = mf.getMainAttributes();
-                String name = attrs.getValue("Bundle-Name");
-                String version = attrs.getValue("Bundle-Version");
-                if ("Joda-Time".equals(name) && version != null) {
-                    return version;
-                }
-            } catch (Exception e) {
-                InternalLogFactory.getLog(JodaTime.class).debug("FYI", e);
-            }
-            return null;
-        }
-    }
-    
-    private static boolean checkExpectedBehavior() {
-        try {
-            return checkTT0031561767() 
-                && checkFormatIso8601Date() 
-                && checkFormatRfc822Date()
-                && checkAlternateIso8601DateFormat() 
-                && checkInvalidDate()
-                && checkParseCompressedIso8601Date() 
-                && checkParseIso8601Date()
-                && checkParseIso8601DateUsingAlternativeFormat()
-                && checkParseRfc822Date()
-                ;
-        } catch (Exception ignore) {
-        }
-        return false;
-    }
-
-    private static boolean checkTT0031561767() throws ParseException {
-        String input = "Fri, 16 May 2014 23:56:46 GMT";
-        Date date = new Date(DateUtils.rfc822DateFormat.parseMillis(input));
-        return input.equals(DateUtils.rfc822DateFormat.print(date.getTime()));
-    }
-
-    private static boolean checkFormatIso8601Date() throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat(
-                "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String expected = sdf.format(date);
-        String actual = DateUtils.iso8601DateFormat.print(date.getTime());
-        if (expected.equals(actual)) {
-            Date expectedDate = sdf.parse(expected);
-            Date actualDate = DateUtils.doParseISO8601Date(actual);
-            return expectedDate.equals(actualDate);
-        }
-        return false;
-    }
-
-    private static boolean checkFormatRfc822Date() throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat(
-                "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String expected = sdf.format(date);
-        String actual = DateUtils.rfc822DateFormat.print(date.getTime());
-        if (expected.equals(actual)) {
-            Date expectedDate = sdf.parse(expected);
-            Date actualDate2 = new Date(DateUtils.rfc822DateFormat.parseMillis(actual));
-            return expectedDate.equals(actualDate2);
-        }
-        return false;
-    }
-
-    private static boolean checkParseCompressedIso8601Date() throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String formatted = sdf.format(date);
-        Date expected = sdf.parse(formatted);
-        Date actual = new Date(DateUtils.compressedIso8601DateFormat.parseMillis(formatted));
-        return expected.equals(actual);
-    }
-
-    private static boolean checkParseRfc822Date() throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat(
-                "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String formatted = sdf.format(date);
-        Date expected = sdf.parse(formatted);
-        Date actual2 = new Date(DateUtils.rfc822DateFormat.parseMillis(formatted));
-        return expected.equals(actual2);
-    }
-
-    private static boolean checkParseIso8601Date() throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat(
-                "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String formatted = sdf.format(date);
-        String alternative = DateUtils.iso8601DateFormat.print(date.getTime());
-        if (formatted.equals(alternative)) {
-            Date expectedDate = sdf.parse(formatted);
-            Date actualDate = DateUtils.doParseISO8601Date(formatted);
-            return expectedDate.equals(actualDate);
-        }
-        return false;
-    }
-
-    private static boolean checkParseIso8601DateUsingAlternativeFormat()
-            throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String formatted = sdf.format(date);
-        String alternative = DateUtils.alternateIso8601DateFormat.print(date
-                .getTime());
-        if (formatted.equals(alternative)) {
-            Date expectedDate = sdf.parse(formatted);
-            Date actualDate = DateUtils.parseISO8601Date(formatted);
-            return expectedDate.equals(actualDate);
-        }
-        return false;
-    }
-
-    private static boolean checkAlternateIso8601DateFormat() throws ParseException {
-        Date date = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
-        String expected = sdf.format(date);
-        String actual = DateUtils.alternateIso8601DateFormat.print(date
-                .getTime());
-        if (expected.equals(actual)) {
-            Date expectedDate = sdf.parse(expected);
-            DateTime actualDateTime = DateUtils.alternateIso8601DateFormat
-                    .parseDateTime(actual);
-            return expectedDate.getTime() == actualDateTime.getMillis();
-        }
-        return false;
-    }
-
-    private static boolean checkInvalidDate() {
-        final String input = "2014-03-06T14:28:58.000Z.000Z";
-        try {
-            DateUtils.doParseISO8601Date(input);
-            return false;
-        } catch (RuntimeException expected) {
-        }
-        return true;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/json/Jackson.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/json/Jackson.java
--- ./src/main/java/com/amazonaws/util/json/Jackson.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/json/Jackson.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,99 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.util.json;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
-
-import com.amazonaws.SdkClientException;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectWriter;
-
-public enum Jackson {
-    ;
-    private static final ObjectMapper objectMapper = new ObjectMapper();
-    static {
-        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
-        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-    };
-    private static final ObjectWriter writer = objectMapper.writer();
-    private static final ObjectWriter prettyWriter = objectMapper.writerWithDefaultPrettyPrinter();
-
-    public static String toJsonPrettyString(Object value) {
-        try {
-            return prettyWriter.writeValueAsString(value);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    public static String toJsonString(Object value) {
-        try {
-            return writer.writeValueAsString(value);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Returns the deserialized object from the given json string and target
-     * class; or null if the given json string is null.
-     */
-    public static <T> T fromJsonString(String json, Class<T> clazz) {
-        if (json == null)
-            return null;
-        try {
-            return objectMapper.readValue(json, clazz);
-        } catch (Exception e) {
-            throw new SdkClientException("Unable to parse Json String.", e);
-        }
-    }
-
-    public static JsonNode jsonNodeOf(String json) {
-        return fromJsonString(json, JsonNode.class);
-    }
-
-    public static JsonGenerator jsonGeneratorOf(Writer writer) throws IOException {
-        return new JsonFactory().createGenerator(writer);
-    }
-
-    public static <T> T loadFrom(File file, Class<T> clazz) throws IOException {
-        try {
-            return objectMapper.readValue(file, clazz);
-        } catch (IOException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    public static ObjectMapper getObjectMapper() {
-        return objectMapper;
-    }
-
-    public static ObjectWriter getWriter() {
-        return writer;
-    }
-
-    public static ObjectWriter getPrettywriter() {
-        return prettyWriter;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/LengthCheckInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/LengthCheckInputStream.java
--- ./src/main/java/com/amazonaws/util/LengthCheckInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/LengthCheckInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,189 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.NotThreadSafe;
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * Used to perform length check to ensure the number of bytes read from the
- * underlying input stream is the same as the expected total.
- */
-@NotThreadSafe
-public class LengthCheckInputStream extends SdkFilterInputStream {
-    public static final boolean INCLUDE_SKIPPED_BYTES = true;
-    public static final boolean EXCLUDE_SKIPPED_BYTES = false;
-    /**
-     * Total number of bytes expected to be read from the underlying input
-     * stream.
-     */
-    private final long expectedLength;
-    /**
-     * True if skipped bytes are to be included as part of the data length;
-     * false otherwise.
-     */
-    private final boolean includeSkipped;
-    /**
-     * The length of the data read from the underlying input stream so far.
-     */
-    private long dataLength;
-    private long marked; // used for mark-and-reset purposes
-    
-    /**
-     * Used for diagnostic purposes. True if reset has been called since last
-     * marked; False otherwise.
-     */
-    private boolean resetSinceLastMarked;
-    private int markCount, resetCount;
-
-    /**
-     * Constructs an input stream that performs length check to ensure the
-     * number of bytes read from the underlying input stream is the same as the
-     * expected total.
-     * 
-     * @param in
-     *            the underlying input stream
-     * @param expectedLength
-     *            the total length of the data in bytes expected to be read from
-     *            the underlying input stream; must be non-negative.
-     * @param includeSkipped
-     *            true if bytes skipped are to be considered as part of the data
-     *            length; false otherwise. Typically, this parameter should be
-     *            set to false for uploading data to AWS, but set to true for
-     *            receiving data from AWS.
-     */
-    public LengthCheckInputStream(InputStream in, long expectedLength,
-            boolean includeSkipped) {
-        super(in);
-        if (expectedLength < 0)
-            throw new IllegalArgumentException();
-        this.expectedLength = expectedLength;
-        this.includeSkipped = includeSkipped;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @throws SdkClientException
-     *             if the data length read has exceeded the expected total, or
-     *             if the total data length is not the same as the expected
-     *             total.
-     */
-    @Override
-    public int read() throws IOException {
-        final int c = super.read();
-        if (c >= 0)
-            dataLength++;
-        checkLength(c == -1);
-        return c;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @throws SdkClientException
-     *             if the data length read has exceeded the expected total, or
-     *             if the total data length is not the same as the expected
-     *             total.
-     */
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        int readLen = super.read(b, off, len);
-        dataLength += readLen >= 0 ? readLen : 0;
-        checkLength(readLen == -1);
-        return readLen;
-    }
-
-    @Override
-    public void mark(int readlimit) {
-        if (markSupported()) {
-            super.mark(readlimit);
-            marked = dataLength;
-            markCount++;
-            resetSinceLastMarked = false;
-        }
-    }
-
-    @Override
-    public void reset() throws IOException {
-        if (markSupported()) {
-            super.reset();
-            dataLength = marked;
-            resetCount++;
-            resetSinceLastMarked = true;
-        } else {
-            throw new IOException("mark/reset not supported");
-        }
-    }
-
-    /**
-     * Checks the data length read so far against the expected total.
-     * 
-     * @param eof
-     *            true if end of stream has been encountered; false otherwise
-     * 
-     * @throws SdkClientException
-     *             if the data length read has exceeded the expected total, or
-     *             if the total data length is not the same as the expected
-     *             total.
-     */
-    private void checkLength(boolean eof) {
-        if (eof) {
-            if (dataLength != expectedLength) {
-                throw new SdkClientException(
-                        "Data read has a different length than the expected: "
-                                + diagnosticInfo());
-            }
-        } else if (dataLength > expectedLength) {
-            throw new SdkClientException("More data read than expected: "
-                    + diagnosticInfo());
-        }
-    }
-
-    private String diagnosticInfo() {
-        return new StringBuilder()
-            .append("dataLength=").append(dataLength)
-            .append("; expectedLength=").append(expectedLength)
-            .append("; includeSkipped=").append(includeSkipped)
-            .append("; in.getClass()=").append(in.getClass())
-            .append("; markedSupported=").append(markSupported())
-            .append("; marked=").append(marked)
-            .append("; resetSinceLastMarked=").append(resetSinceLastMarked)
-            .append("; markCount=").append(markCount)
-            .append("; resetCount=").append(resetCount)
-            .toString();
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @throws SdkClientException
-     *             if {@link #includeSkipped} is true and the data length
-     *             skipped has exceeded the expected total.
-     */
-    @Override
-    public long skip(long n) throws IOException {
-        final long skipped = super.skip(n);
-        if (includeSkipped && skipped > 0) {
-            dataLength += skipped;
-            checkLength(false);
-        }
-        return skipped;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Md5Utils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Md5Utils.java
--- ./src/main/java/com/amazonaws/util/Md5Utils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Md5Utils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,106 +0,0 @@
-/*
- * Copyright 2012-2018 Amazon Technologies, Inc.
- *
- * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
- * for applicable license terms and NOTICE.txt for applicable notices.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Utility methods for computing MD5 sums.
- */
-public class Md5Utils {
-    private static final int SIXTEEN_K = 1 << 14;
-    /**
-     * Computes the MD5 hash of the data in the given input stream and returns
-     * it as an array of bytes.
-     * Note this method closes the given input stream upon completion.
-     */
-    public static byte[] computeMD5Hash(InputStream is) throws IOException {
-        BufferedInputStream bis = new BufferedInputStream(is);
-        try {
-            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
-            byte[] buffer = new byte[SIXTEEN_K];
-            int bytesRead;
-            while ( (bytesRead = bis.read(buffer, 0, buffer.length)) != -1 ) {
-                messageDigest.update(buffer, 0, bytesRead);
-            }
-            return messageDigest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            // should never get here
-            throw new IllegalStateException(e);
-        } finally {
-            try {
-                bis.close();
-            } catch (Exception e) {
-                LogFactory.getLog(Md5Utils.class).debug(
-                        "Unable to close input stream of hash candidate: " + e);
-            }
-        }
-    }
-
-    /**
-     * Returns the MD5 in base64 for the data from the given input stream.
-     * Note this method closes the given input stream upon completion.
-     */
-    public static String md5AsBase64(InputStream is) throws IOException {
-        return Base64.encodeAsString(computeMD5Hash(is));
-    }
-
-    /**
-     * Computes the MD5 hash of the given data and returns it as an array of
-     * bytes.
-     */
-    public static byte[] computeMD5Hash(byte[] input) {
-        try {
-            MessageDigest md = MessageDigest.getInstance("MD5");
-            return md.digest(input);
-        } catch (NoSuchAlgorithmException e) {
-            // should never get here
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Returns the MD5 in base64 for the given byte array.
-     */
-    public static String md5AsBase64(byte[] input) {
-        return Base64.encodeAsString(computeMD5Hash(input));
-    }
-
-    /**
-     * Computes the MD5 of the given file.
-     */
-    public static byte[] computeMD5Hash(File file) throws FileNotFoundException, IOException {
-        return computeMD5Hash(new FileInputStream(file));
-    }
-
-    /**
-     * Returns the MD5 in base64 for the given file.
-     */
-    public static String md5AsBase64(File file) throws FileNotFoundException, IOException {
-        return Base64.encodeAsString(computeMD5Hash(file));
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/MetadataCache.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/MetadataCache.java
--- ./src/main/java/com/amazonaws/util/MetadataCache.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/MetadataCache.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.ResponseMetadata;
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Interface for caches interacting with response metadata.
- */
-@SdkInternalApi
-public interface MetadataCache {
-
-    /**
-     * Adds a new entry to this cache, possibly evicting the oldest entry if the
-     * cache is at its size limit.
-     *
-     * @param obj
-     *            The key by which to store the metadata.
-     * @param metadata
-     *            The metadata for this entry.
-     */
-    void add(Object obj, ResponseMetadata metadata);
-
-    /**
-     * Returns the response metadata associated with the specified object, or
-     * null if no metadata is associated with that object.
-     *
-     * @param obj
-     *            The key by which the desired metadata is stored.
-     *
-     * @return The response metadata associated with the given object key,
-     *         otherwise null if no metadata is associated with that object.
-     */
-    ResponseMetadata get(Object obj);
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/NamespaceRemovingInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NamespaceRemovingInputStream.java
--- ./src/main/java/com/amazonaws/util/NamespaceRemovingInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NamespaceRemovingInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,171 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * FilterInputStream implementation that wraps an InputStream containing an XML
- * document, and removes the XML namespace attribute from the XML document.
- */
-class NamespaceRemovingInputStream extends SdkFilterInputStream {
-
-    /** look ahead buffer */
-    private byte[] lookAheadData = new byte[200];
-
-    /** Set to true once the namespace has been removed */
-    private boolean hasRemovedNamespace = false;
-
-    /**
-     * Constructs a new NamespaceRemovingInputStream wrapping the specified
-     * InputStream.
-     *
-     * @param in
-     *            The InputStream containing an XML document whose XML namespace
-     *            is to be removed.
-     */
-    public NamespaceRemovingInputStream(InputStream in) {
-        // Wrap our input stream in a buffered input stream to ensure
-        // that it support mark/reset
-        super(new BufferedInputStream(in));
-    }
-
-    /* (non-Javadoc)
-     * @see java.io.FilterInputStream#read()
-     */
-    @Override
-    public int read() throws IOException {
-        abortIfNeeded();
-        int b = in.read();
-        if (b == 'x' && !hasRemovedNamespace) {
-            lookAheadData[0] = (byte)b;
-            in.mark(lookAheadData.length);
-            int bytesRead = in.read(lookAheadData, 1, lookAheadData.length - 1);
-            in.reset();
-
-            String string = new String(lookAheadData, 0, bytesRead + 1, StringUtils.UTF8);
-
-            int numberCharsMatched = matchXmlNamespaceAttribute(string);
-            if (numberCharsMatched > 0) {
-                for (int i = 0; i < numberCharsMatched - 1; i++) {
-                    in.read();
-                }
-                b = in.read();
-                hasRemovedNamespace = true;
-            }
-        }
-
-        return b;
-    }
-
-    /* (non-Javadoc)
-     * @see java.io.FilterInputStream#read(byte[], int, int)
-     */
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        for (int i = 0; i < len; i++) {
-            int j = this.read();
-            if (j == -1) {
-                if (i == 0) return -1;
-                return i;
-            }
-
-            b[i + off] = (byte)j;
-        }
-
-        return len;
-    }
-
-    /* (non-Javadoc)
-     * @see java.io.FilterInputStream#read(byte[])
-     */
-    @Override
-    public int read(byte[] b) throws IOException {
-        return this.read(b, 0, b.length);
-    }
-
-    /**
-     * Checks if the string starts with a complete XML namespace attribute, and
-     * if so, returns the number of characters that match.
-     *
-     * @param s
-     *            The string to check for an XML namespace definition.
-     *
-     * @return -1 if no XML namespace definition was found, otherwise the length
-     *         of the identified XML namespace definition.
-     */
-    private int matchXmlNamespaceAttribute(String s) {
-        /*
-         * The regex we're simulating is: "xmlns\\s*=\\s*\".+?\".*"
-         */
-        StringPrefixSlicer stringSlicer = new StringPrefixSlicer(s);
-        if (stringSlicer.removePrefix("xmlns") == false) return -1;
-
-        stringSlicer.removeRepeatingPrefix(" ");
-        if (stringSlicer.removePrefix("=") == false) return -1;
-        stringSlicer.removeRepeatingPrefix(" ");
-
-        if (stringSlicer.removePrefix("\"") == false) return -1;
-        if (stringSlicer.removePrefixEndingWith("\"") == false) return -1;
-
-        return s.length() - stringSlicer.getString().length();
-    }
-
-    /**
-     * Utility class to help test and remove specified prefixes from a string.
-     */
-    private static final class StringPrefixSlicer {
-        private String s;
-
-        public StringPrefixSlicer(String s) {
-            this.s = s;
-        }
-
-        /**
-         * @return The remaining String (minus any prefixes that have been
-         *         removed).
-         */
-        public String getString() {
-            return s;
-        }
-
-        public boolean removePrefix(String prefix) {
-            if (s.startsWith(prefix) == false) return false;
-            s = s.substring(prefix.length());
-            return true;
-        }
-
-        public boolean removeRepeatingPrefix(String prefix) {
-            if (s.startsWith(prefix) == false) return false;
-
-            while (s.startsWith(prefix)) {
-                s = s.substring(prefix.length());
-            }
-            return true;
-        }
-
-        public boolean removePrefixEndingWith(String marker) {
-            int i = s.indexOf(marker);
-            if (i < 0) return false;
-            s = s.substring(i + marker.length());
-            return true;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/NameValuePair.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NameValuePair.java
--- ./src/main/java/com/amazonaws/util/NameValuePair.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NameValuePair.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package com.amazonaws.util;
-
-/**
- * A name / value pair parameter used as an element of HTTP messages.
- * <pre>
- * parameter               = attribute "=" value
- * attribute               = token
- * value                   = token | quoted-string
- * </pre>
- *
- *
- * @since 4.0
- */
-interface NameValuePair {
-
-    String getName();
-
-    String getValue();
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/NullResponseMetadataCache.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NullResponseMetadataCache.java
--- ./src/main/java/com/amazonaws/util/NullResponseMetadataCache.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NullResponseMetadataCache.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,39 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights
- * Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.SdkClientException;
-import com.amazonaws.ResponseMetadata;
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * No-op response metadata cache used when a client instance is configured
- * without response metadata caching enabled.
- */
-@SdkInternalApi
-public class NullResponseMetadataCache implements MetadataCache {
-
-    @Override
-    public void add(Object obj, ResponseMetadata metadata) {
-        // deliberately left blank
-    }
-
-    @Override
-    public ResponseMetadata get(Object obj) {
-        throw new SdkClientException("Response metadata caching is not enabled");
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/NumberUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NumberUtils.java
--- ./src/main/java/com/amazonaws/util/NumberUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/NumberUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,34 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-public final class NumberUtils {
-
-    private NumberUtils() {
-    }
-
-    /**
-     * @param toParse
-     * @return {@link Integer} or null if string can't be parsed
-     */
-    public static Integer tryParseInt(String toParse) {
-        try {
-            return Integer.parseInt(toParse);
-        } catch (NumberFormatException e) {
-            return null;
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/ResponseMetadataCache.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ResponseMetadataCache.java
--- ./src/main/java/com/amazonaws/util/ResponseMetadataCache.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ResponseMetadataCache.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map.Entry;
-
-import com.amazonaws.ResponseMetadata;
-import com.amazonaws.annotation.SdkInternalApi;
-
-/**
- * Cache of response metadata for recently executed requests for diagnostic
- * purposes. This cache has a max size and as entries are added, the oldest
- * entry is aged out once the max size has been reached.
- */
-@SdkInternalApi
-public class ResponseMetadataCache implements MetadataCache {
-    private final InternalCache internalCache;
-
-    /**
-     * Creates a new cache that will contain, at most the specified number of
-     * entries.
-     *
-     * @param maxEntries
-     *            The maximum size of this cache.
-     */
-    public ResponseMetadataCache(int maxEntries) {
-        internalCache = new InternalCache(maxEntries);
-    }
-
-    @Override
-    public synchronized void add(Object obj, ResponseMetadata metadata) {
-        if (obj == null) return;
-        internalCache.put(System.identityHashCode(obj), metadata);
-    }
-
-    @Override
-    public synchronized ResponseMetadata get(Object obj) {
-        // System.identityHashCode isn't guaranteed to be unique
-        // on all platforms, but should be reasonable enough to use
-        // for a few requests at a time.  We can always easily move
-        // to our own unique IDs if needed.
-        return internalCache.get(System.identityHashCode(obj));
-    }
-
-    /**
-     * Simple implementation of LinkedHashMap that overrides the
-     * <code>removeEldestEntry</code> method to turn LinkedHashMap into a
-     * FIFO cache that automatically evicts old entries.
-     */
-    private static final class InternalCache extends LinkedHashMap<Integer, ResponseMetadata> {
-        private static final long serialVersionUID = 1L;
-        private int maxSize;
-
-        InternalCache(int maxSize) {
-            super(maxSize);
-            this.maxSize = maxSize;
-        }
-
-        @Override
-        protected boolean removeEldestEntry(Entry<Integer,ResponseMetadata> eldest) {
-            return size() > maxSize;
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/RuntimeHttpUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/RuntimeHttpUtils.java
--- ./src/main/java/com/amazonaws/util/RuntimeHttpUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/RuntimeHttpUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,256 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.ClientConfiguration;
-import com.amazonaws.Protocol;
-import com.amazonaws.Request;
-import com.amazonaws.SdkClientException;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.NTCredentials;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.params.ConnRoutePNames;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-
-public class RuntimeHttpUtils {
-    private static final String COMMA = ", ";
-    private static final String SPACE = " ";
-
-    private static final String AWS_EXECUTION_ENV_PREFIX = "exec-env/";
-    private static final String AWS_EXECUTION_ENV_NAME = "AWS_EXECUTION_ENV";
-
-
-    /**
-     * Fetches a file from the URI given and returns an input stream to it.
-     *
-     * @param uri the uri of the file to fetch
-     * @param config optional configuration overrides
-     * @return an InputStream containing the retrieved data
-     * @throws IOException on error
-     */
-    @SuppressWarnings("deprecation")
-    public static InputStream fetchFile(
-            final URI uri,
-            final ClientConfiguration config) throws IOException {
-
-        HttpParams httpClientParams = new BasicHttpParams();
-        HttpProtocolParams.setUserAgent(
-                httpClientParams, getUserAgent(config, null));
-
-        HttpConnectionParams.setConnectionTimeout(
-                httpClientParams, getConnectionTimeout(config));
-        HttpConnectionParams.setSoTimeout(
-                httpClientParams, getSocketTimeout(config));
-
-        DefaultHttpClient httpclient = new DefaultHttpClient(httpClientParams);
-
-        if (config != null) {
-            String proxyHost = config.getProxyHost();
-            int proxyPort = config.getProxyPort();
-
-            if (proxyHost != null && proxyPort > 0) {
-
-                HttpHost proxy = new HttpHost(proxyHost, proxyPort);
-                httpclient.getParams().setParameter(
-                        ConnRoutePNames.DEFAULT_PROXY, proxy);
-
-                if (config.getProxyUsername() != null
-                    && config.getProxyPassword() != null) {
-
-                    httpclient.getCredentialsProvider().setCredentials(
-                            new AuthScope(proxyHost, proxyPort),
-                            new NTCredentials(config.getProxyUsername(),
-                                              config.getProxyPassword(),
-                                              config.getProxyWorkstation(),
-                                              config.getProxyDomain()));
-                }
-            }
-        }
-
-        HttpResponse response = httpclient.execute(new HttpGet(uri));
-
-        if (response.getStatusLine().getStatusCode() != 200) {
-            throw new IOException("Error fetching file from " + uri + ": "
-                                  + response);
-        }
-
-        return new HttpClientWrappingInputStream(
-                httpclient,
-                response.getEntity().getContent());
-    }
-
-    public static String getUserAgent(final ClientConfiguration config, final String userAgentMarker) {
-        String userDefinedPrefix = config != null ? config.getUserAgentPrefix() : "";
-        String userDefinedSuffix = config != null ? config.getUserAgentSuffix() : "";
-        String awsExecutionEnvironment = getEnvironmentVariable(AWS_EXECUTION_ENV_NAME);
-
-        StringBuilder userAgent = new StringBuilder(userDefinedPrefix.trim());
-
-        if(!ClientConfiguration.DEFAULT_USER_AGENT.equals(userDefinedPrefix)) {
-            userAgent.append(COMMA).append(ClientConfiguration.DEFAULT_USER_AGENT);
-        }
-
-        if(StringUtils.hasValue(userDefinedSuffix)) {
-            userAgent.append(COMMA).append(userDefinedSuffix.trim());
-        }
-
-        if(StringUtils.hasValue(awsExecutionEnvironment)) {
-            userAgent.append(SPACE).append(AWS_EXECUTION_ENV_PREFIX).append(awsExecutionEnvironment.trim());
-        }
-
-        if(StringUtils.hasValue(userAgentMarker)) {
-            userAgent.append(SPACE).append(userAgentMarker.trim());
-        }
-
-        return userAgent.toString();
-    }
-
-    private static String getEnvironmentVariable(String environmentVariableName) {
-        try {
-            return System.getenv(environmentVariableName);
-        } catch (Exception e) {
-            // Return an empty string if unable to get environment variable
-            return "";
-        }
-    }
-
-    private static int getConnectionTimeout(final ClientConfiguration config) {
-        if (config != null) {
-            return config.getConnectionTimeout();
-        }
-        return ClientConfiguration.DEFAULT_CONNECTION_TIMEOUT;
-    }
-
-    private static int getSocketTimeout(final ClientConfiguration config) {
-        if (config != null) {
-            return config.getSocketTimeout();
-        }
-        return ClientConfiguration.DEFAULT_SOCKET_TIMEOUT;
-    }
-
-    /**
-     * Returns an URI for the given endpoint.
-     * Prefixes the protocol if the endpoint given does not have it.
-     *
-     * @throws IllegalArgumentException if the inputs are null.
-     */
-    public static URI toUri(String endpoint, ClientConfiguration config) {
-
-        if (config == null) {
-            throw new IllegalArgumentException("ClientConfiguration cannot be null");
-        }
-        return toUri(endpoint, config.getProtocol());
-    }
-
-    /**
-     * Returns an URI for the given endpoint.
-     * Prefixes the protocol if the endpoint given does not have it.
-     *
-     * @throws IllegalArgumentException if the inputs are null.
-     */
-    public static URI toUri(String endpoint, Protocol protocol) {
-        if (endpoint == null) {
-            throw new IllegalArgumentException("endpoint cannot be null");
-        }
-
-        /*
-         * If the endpoint doesn't explicitly specify a protocol to use, then
-         * we'll defer to the default protocol specified in the client
-         * configuration.
-         */
-        if (!endpoint.contains("://")) {
-            endpoint = protocol.toString() + "://" + endpoint;
-        }
-
-        try {
-            return new URI(endpoint);
-        } catch (URISyntaxException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    /**
-     * Converts the specified request object into a URL, containing all the specified parameters, the specified request endpoint,
-     * etc.
-     *
-     * @param request                          The request to convert into a URL.
-     * @param removeLeadingSlashInResourcePath Whether the leading slash in resource-path should be removed before appending to
-     *                                         the endpoint.
-     * @param urlEncode                        True if request resource path should be URL encoded
-     * @return A new URL representing the specified request.
-     * @throws SdkClientException If the request cannot be converted to a well formed URL.
-     */
-    @SdkProtectedApi
-    public static URL convertRequestToUrl(Request<?> request,
-                                          boolean removeLeadingSlashInResourcePath,
-                                          boolean urlEncode) {
-        String resourcePath = urlEncode ?
-                SdkHttpUtils.urlEncode(request.getResourcePath(), true)
-                : request.getResourcePath();
-
-        // Removed the padding "/" that was already added into the request's resource path.
-        if (removeLeadingSlashInResourcePath
-            && resourcePath.startsWith("/")) {
-            resourcePath = resourcePath.substring(1);
-        }
-
-        // Some http client libraries (e.g. Apache HttpClient) cannot handle
-        // consecutive "/"s between URL authority and path components.
-        // So we escape "////..." into "/%2F%2F%2F...", in the same way as how
-        // we treat consecutive "/"s in AmazonS3Client#presignRequest(...)
-
-        String urlPath = "/" + resourcePath;
-        urlPath = urlPath.replaceAll("(?<=/)/", "%2F");
-        StringBuilder url = new StringBuilder(request.getEndpoint().toString());
-        url.append(urlPath);
-
-        StringBuilder queryParams = new StringBuilder();
-        Map<String, List<String>> requestParams = request.getParameters();
-        for (Map.Entry<String, List<String>> entry : requestParams.entrySet()) {
-            for (String value : entry.getValue()) {
-                queryParams = queryParams.length() > 0 ? queryParams
-                        .append("&") : queryParams.append("?");
-                queryParams.append(SdkHttpUtils.urlEncode(entry.getKey(), false))
-                        .append("=")
-                        .append(SdkHttpUtils.urlEncode(value, false));
-            }
-        }
-        url.append(queryParams.toString());
-
-        try {
-            return new URL(url.toString());
-        } catch (MalformedURLException e) {
-            throw new SdkClientException(
-                    "Unable to convert request to well formed URL: " + e.getMessage(), e);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/SdkHttpUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/SdkHttpUtils.java
--- ./src/main/java/com/amazonaws/util/SdkHttpUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/SdkHttpUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,216 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.amazonaws.SignableRequest;
-import com.amazonaws.http.HttpMethodName;
-
-public class SdkHttpUtils {
-
-    private static final String DEFAULT_ENCODING = "UTF-8";
-
-    /**
-     * Regex which matches any of the sequences that we need to fix up after
-     * URLEncoder.encode().
-     */
-    private static final Pattern ENCODED_CHARACTERS_PATTERN;
-    static {
-        StringBuilder pattern = new StringBuilder();
-
-        pattern
-            .append(Pattern.quote("+"))
-            .append("|")
-            .append(Pattern.quote("*"))
-            .append("|")
-            .append(Pattern.quote("%7E"))
-            .append("|")
-            .append(Pattern.quote("%2F"));
-
-        ENCODED_CHARACTERS_PATTERN = Pattern.compile(pattern.toString());
-    }
-
-    /**
-     * Encode a string for use in the path of a URL; uses URLEncoder.encode,
-     * (which encodes a string for use in the query portion of a URL), then
-     * applies some postfilters to fix things up per the RFC. Can optionally
-     * handle strings which are meant to encode a path (ie include '/'es
-     * which should NOT be escaped).
-     *
-     * @param value the value to encode
-     * @param path true if the value is intended to represent a path
-     * @return the encoded value
-     */
-    public static String urlEncode(final String value, final boolean path) {
-        if (value == null) {
-            return "";
-        }
-
-        try {
-            String encoded = URLEncoder.encode(value, DEFAULT_ENCODING);
-
-            Matcher matcher = ENCODED_CHARACTERS_PATTERN.matcher(encoded);
-            StringBuffer buffer = new StringBuffer(encoded.length());
-
-            while (matcher.find()) {
-                String replacement = matcher.group(0);
-
-                if ("+".equals(replacement)) {
-                    replacement = "%20";
-                } else if ("*".equals(replacement)) {
-                    replacement = "%2A";
-                } else if ("%7E".equals(replacement)) {
-                    replacement = "~";
-                } else if (path && "%2F".equals(replacement)) {
-                    replacement = "/";
-                }
-
-                matcher.appendReplacement(buffer, replacement);
-            }
-
-            matcher.appendTail(buffer);
-            return buffer.toString();
-
-        } catch (UnsupportedEncodingException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Decode a string for use in the path of a URL; uses URLDecoder.decode,
-     * which decodes a string for use in the query portion of a URL.
-     *
-     * @param value The value to decode
-     * @return The decoded value if parameter is not null, otherwise, null is returned.
-     */
-    public static String urlDecode(final String value) {
-        if (value == null) {
-            return null;
-        }
-
-        try {
-            return URLDecoder.decode(value, DEFAULT_ENCODING);
-
-        } catch (UnsupportedEncodingException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Returns true if the specified URI is using a non-standard port (i.e. any
-     * port other than 80 for HTTP URIs or any port other than 443 for HTTPS
-     * URIs).
-     *
-     * @param uri
-     *
-     * @return True if the specified URI is using a non-standard port, otherwise
-     *         false.
-     */
-    public static boolean isUsingNonDefaultPort(URI uri) {
-        String scheme = StringUtils.lowerCase(uri.getScheme());
-        int port = uri.getPort();
-
-        if (port <= 0) return false;
-        if (scheme.equals("http") && port == 80) return false;
-        if (scheme.equals("https") && port == 443) return false;
-
-        return true;
-    }
-
-    public static boolean usePayloadForQueryParameters(SignableRequest<?> request) {
-        boolean requestIsPOST = HttpMethodName.POST.equals(request.getHttpMethod());
-        boolean requestHasNoPayload = (request.getContent() == null);
-
-        return requestIsPOST && requestHasNoPayload;
-    }
-
-    /**
-     * Creates an encoded query string from all the parameters in the specified
-     * request.
-     *
-     * @param request
-     *            The request containing the parameters to encode.
-     *
-     * @return Null if no parameters were present, otherwise the encoded query
-     *         string for the parameters present in the specified request.
-     */
-    public static String encodeParameters(SignableRequest<?> request) {
-
-        final Map<String, List<String>> requestParams = request.getParameters();
-
-        if (requestParams.isEmpty()) return null;
-
-        final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
-
-        for (Entry<String, List<String>> entry : requestParams.entrySet()) {
-            String parameterName = entry.getKey();
-            for (String value : entry.getValue()) {
-                nameValuePairs
-                    .add(new BasicNameValuePair(parameterName, value));
-            }
-        }
-
-        return URLEncodedUtils.format(nameValuePairs, DEFAULT_ENCODING);
-    }
-
-    /**
-     * Append the given path to the given baseUri.
-     * By default, all slash characters in path will not be url-encoded.
-     */
-    public static String appendUri(String baseUri, String path) {
-        return appendUri(baseUri, path, false);
-    }
-
-    /**
-     * Append the given path to the given baseUri.
-     *
-     * @param baseUri The URI to append to (required, may be relative)
-     * @param path The path to append (may be null or empty).  Path should be pre-encoded.
-     * @param escapeDoubleSlash Whether double-slash in the path should be escaped to "/%2F"
-     * @return The baseUri with the path appended
-     */
-    public static String appendUri(final String baseUri, String path, final boolean escapeDoubleSlash) {
-        String resultUri = baseUri;
-        if (path != null && path.length() > 0) {
-            if (path.startsWith("/")) {
-                // trim the trailing slash in baseUri, since the path already starts with a slash
-                if (resultUri.endsWith("/")) {
-                    resultUri = resultUri.substring(0, resultUri.length() - 1);
-                }
-            } else if (!resultUri.endsWith("/")) {
-                resultUri += "/";
-            }
-            if (escapeDoubleSlash) {
-                resultUri += path.replace("//", "/%2F");
-            } else {
-                resultUri += path;
-            }
-        } else if (!resultUri.endsWith("/")) {
-            resultUri += "/";
-        }
-
-        return resultUri;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/util/SdkRuntime.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/SdkRuntime.java
--- ./src/main/java/com/amazonaws/util/SdkRuntime.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/SdkRuntime.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-public enum SdkRuntime {
-    ;
-
-    /**
-     * Returns true if the current operation should abort; false otherwise.
-     * Note the interrupted status of the thread is cleared by this method.
-     */
-    public static boolean shouldAbort() {
-        return Thread.interrupted();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/ServiceClientHolderInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ServiceClientHolderInputStream.java
--- ./src/main/java/com/amazonaws/util/ServiceClientHolderInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ServiceClientHolderInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,39 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon Technologies, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *    http://aws.amazon.com/apache2.0
- *
- * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.InputStream;
-
-import com.amazonaws.AmazonWebServiceClient;
-import com.amazonaws.internal.SdkFilterInputStream;
-
-/**
- * This wrapper input stream holds a reference to the service client. This is
- * mainly done to avoid the AmazonWebServiceClient object being garbage
- * collected when the client reads data from the input stream.
- * 
- */
-public class ServiceClientHolderInputStream extends SdkFilterInputStream {
-
-	
-	@SuppressWarnings("unused")
-	private AmazonWebServiceClient client;
-
-	public ServiceClientHolderInputStream(InputStream in,
-			AmazonWebServiceClient client) {
-		super(in);
-		this.client = client;
-	}	
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/StringInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringInputStream.java
--- ./src/main/java/com/amazonaws/util/StringInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,44 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-import static com.amazonaws.util.StringUtils.UTF8;
-
-import java.io.ByteArrayInputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Simple wrapper for ByteArrayInputStream that will automatically encode the
- * string as UTF-8 data, and still allows access to the original string.
- */
-public class StringInputStream extends ByteArrayInputStream {
-
-    private final String string;
-
-    public StringInputStream(String s) throws UnsupportedEncodingException {
-        super(s.getBytes(UTF8));
-        this.string = s;
-    }
-
-    /**
-     * Returns the original string specified when this input stream was
-     * constructed.
-     *
-     * @return The original string specified when this input stream was
-     *         constructed.
-     */
-    public String getString() {
-        return string;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/StringMapBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringMapBuilder.java
--- ./src/main/java/com/amazonaws/util/StringMapBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/StringMapBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,26 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-/**
- * A convenient map builder for Strings.
- */
-public class StringMapBuilder extends
-    ImmutableMapParameter.Builder<String, String> {
-    public StringMapBuilder() {}
-    public StringMapBuilder(String key, String value) {
-        super.put(key, value);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/Throwables.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Throwables.java
--- ./src/main/java/com/amazonaws/util/Throwables.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/Throwables.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,78 +0,0 @@
-/*
- * Copyright 2013-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.AbortedException;
-import com.amazonaws.AmazonClientException;
-
-/**
- * Utility for use with errors or exceptions.
- */
-public enum Throwables {
-    ;
-    /**
-     * Returns the root cause of the given throwable, or null if the given
-     * throwable is null. If the root cause is over 1000 level deep, the
-     * original throwable will be returned defensively as this is heuristically
-     * considered a circular reference, however unlikely.
-     */
-    public static Throwable getRootCause(Throwable orig) {
-        if (orig == null)
-            return orig;
-        Throwable t = orig;
-        // defend against (malicious?) circularity
-        for (int i=0; i < 1000; i++) {
-            Throwable cause = t.getCause();
-            if (cause == null)
-                return t;
-            t = cause;
-        }
-        // Too bad.  Return the original exception.
-        LogFactory.getLog(Throwables.class).debug(
-            "Possible circular reference detected on " + orig.getClass()
-                    + ": [" + orig + "]");
-        return orig;
-    }
-
-    /**
-     * Used to help perform common throw-up with minimal wrapping.
-     */
-    public static RuntimeException failure(Throwable t) {
-        if (t instanceof RuntimeException)
-            return (RuntimeException)t;
-        if (t instanceof Error)
-            throw (Error)t;
-        return t instanceof InterruptedException
-             ? new AbortedException(t)
-             : new AmazonClientException(t);
-    }
-
-    /**
-     * Same as {@link #failure(Throwable)}, but the given errmsg will be used if
-     * it was wrapped as either an {@link AmazonClientException} or
-     * {@link AbortedException}.
-     */
-    public static RuntimeException failure(Throwable t, String errmsg) {
-        if (t instanceof RuntimeException)
-            return (RuntimeException)t;
-        if (t instanceof Error)
-            throw (Error)t;
-        return t instanceof InterruptedException 
-             ? new AbortedException(errmsg, t)
-             : new AmazonClientException(errmsg, t);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/TimingInfoFullSupport.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/TimingInfoFullSupport.java
--- ./src/main/java/com/amazonaws/util/TimingInfoFullSupport.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/TimingInfoFullSupport.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,142 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.annotation.NotThreadSafe;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.LogFactory;
-
-/**
- * In contrast to {@link TimingInfo}, which is intended to be a minimal support
- * of the timing info, this class is the full support of timing info including
- * features related to sub-measurements and counters.
- * <p>
- * This class is instantiated instead of {@link TimingInfo} when
- * request metric collection is required during a particular service
- * request/response cycle.
- */
-@NotThreadSafe
-class TimingInfoFullSupport extends TimingInfo {
-    private final Map<String, List<TimingInfo>> subMeasurementsByName = new HashMap<String, List<TimingInfo>>();
-    private final Map<String, Number> countersByName = new HashMap<String, Number>();
-
-    /**
-     * A private ctor to facilitate the deprecation of using millisecond and
-     * migration to using nanosecond for timing measurement.
-     * 
-     * @param startEpochTimeMilli start time since epoch in millisecond
-     * @param startTimeNano start time in nanosecond
-     * @param endTimeNano end time in nanosecond; or null if not known
-     * 
-     * @see TimingInfo#startTimingFullSupport()
-     * @see TimingInfo#startTimingFullSupport(long)
-     * @see TimingInfo#newTimingInfoFullSupport(long, long)
-     * @see TimingInfo#newTimingInfoFullSupport(long, long, long)
-     */
-    TimingInfoFullSupport(Long startEpochTimeMilli, long startTimeNano, Long endTimeNano) {
-        super(startEpochTimeMilli, startTimeNano, endTimeNano);
-    }
-
-    @Override
-    public void addSubMeasurement(String subMeasurementName, TimingInfo ti) {
-        List<TimingInfo> timings = subMeasurementsByName.get(subMeasurementName);
-        if (timings == null) {
-            timings = new ArrayList<TimingInfo>();
-            subMeasurementsByName.put(subMeasurementName, timings);
-        }
-        if (ti.isEndTimeKnown()) {
-            timings.add(ti);
-        } else {
-            LogFactory.getLog(getClass()).debug(
-                "Skip submeasurement timing info with no end time for "
-                + subMeasurementName);
-        }
-    }
-
-    @Override
-    public TimingInfo getSubMeasurement(String subMeasurementName) {
-        return getSubMeasurement(subMeasurementName, 0);
-    }
-
-    @Override
-    public TimingInfo getSubMeasurement(String subMesurementName, int index) {
-
-        List<TimingInfo> timings = subMeasurementsByName.get(subMesurementName);
-        if (index < 0 || timings == null || timings.size() == 0
-                || index >= timings.size()) {
-            return null;
-        }
-
-        return timings.get(index);
-    }
-
-    @Override
-    public TimingInfo getLastSubMeasurement(String subMeasurementName) {
-
-        if (subMeasurementsByName == null || subMeasurementsByName.size() == 0) {
-            return null;
-        }
-
-        List<TimingInfo> timings = subMeasurementsByName.get(subMeasurementName);
-        if (timings == null || timings.size() == 0) {
-            return null;
-        }
-
-        return timings.get(timings.size() - 1);
-    }
-
-    @Override
-    public List<TimingInfo> getAllSubMeasurements(String subMeasurementName) {
-        return subMeasurementsByName.get(subMeasurementName);
-    }
-
-    @Override
-    public Map<String, List<TimingInfo>> getSubMeasurementsByName() {
-        return subMeasurementsByName;
-    }
-
-    @Override
-    public Number getCounter(String key) {
-        return countersByName.get(key);
-    }
-
-    @Override
-    public Map<String, Number> getAllCounters() {
-        return countersByName;
-    }
-
-    @Override
-    public void setCounter(String key, long count) {
-        countersByName.put(key, count);
-    }
-
-    @Override
-    public void incrementCounter(String key) {
-
-        int count = 0;
-        Number counter = getCounter(key);
-
-        if (counter != null) {
-            count = counter.intValue();
-        }
-
-        setCounter(key, ++count);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/TimingInfo.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/TimingInfo.java
--- ./src/main/java/com/amazonaws/util/TimingInfo.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/TimingInfo.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,271 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.annotation.NotThreadSafe;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Used both as a base class and a minimal support of timing info.
- * <p>
- * In contrast to {@link TimingInfoFullSupport}, which is intended to be a full
- * support of the timing info, this class only provides a minimal support of
- * start and end time (ie with no-ops for sub-event measurements) for backward
- * compatiblity reasons.
- * <p>
- * This class is instantiated instead of {@link TimingInfoFullSupport} when
- * request metric collection is not required during a particular service
- * request/response cycle.
- */
-@NotThreadSafe
-public class TimingInfo {
-    static final int UNKNOWN = -1;
-    /**
-     * The wall clock time (as the number of milliseconds since Epoch)
-     * of when the timing measurement starts; or null if unknown.
-     * This field is not meant to be used for timing measurement.
-     * For more info, see:
-     * https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
-     */
-    private final Long startEpochTimeMilli;
-    /** 
-     * Start time in nanosecond used for timing measurement.
-     * Note the value in this field may have nothing to do with
-     * the wall clock time.
-     * The wall clock time of when the timing measurement starts
-     * can optionally be captured in {@link #startEpochTimeMilli}.
-     * For more info, see:
-     * https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
-     * <p>
-     * Note System.nanoTime() can return negative values.
-     */
-    private final long startTimeNano;
-    /** 
-     * End time in nanosecond used for timing measurement or null if unknown.
-     * Note the value in this field is only meant to be used for timing
-     * measurement, and is not directly related to the wall clock time.
-     * For more info, see:
-     * https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
-     * <p>
-     * Note System.nanoTime() can return negative values.
-     */
-    private Long endTimeNano;
-
-    /**
-     * Captures the current wall clock time (since epoch in millisecond)
-     * and the current time (in nanosecond) used for timing measurement.
-     * For more info, see:
-     * https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
-     */
-    public static TimingInfo startTiming() {
-        return new TimingInfo(Long.valueOf(System.currentTimeMillis()), System.nanoTime(), null);
-    }
-
-    /**
-     * Captures the current wall clock time (since epoch in millisecond)
-     * and the current time (in nanosecond) used for timing measurement.
-     * For more info, see:
-     * https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
-     */
-    public static TimingInfo startTimingFullSupport() {
-        return new TimingInfoFullSupport(Long.valueOf(System.currentTimeMillis()), System.nanoTime(), null);
-    }
-
-    /**
-     * Captures the given start time in nanosecond, ignoring the wall clock time.
-     *
-     * @param startTimeNano start time in nanosecond
-     */
-    public static TimingInfo startTimingFullSupport(long startTimeNano) {
-        return new TimingInfoFullSupport(null, startTimeNano, null);
-    }
-
-    /**
-     * Returns a {@link TimingInfoFullSupport} based on the given
-     * start and end time in nanosecond, ignoring the wall clock time.
-     *
-     * @param startTimeNano start time in nanosecond
-     * @param endTimeNano end time in nanosecond
-     */
-    public static TimingInfo newTimingInfoFullSupport(long startTimeNano, long endTimeNano) {
-        return new TimingInfoFullSupport(null, startTimeNano, Long.valueOf(endTimeNano));
-    }
-
-    /**
-     * Returns a {@link TimingInfoFullSupport} based on the given
-     * start time since epoch in millisecond,
-     * and the given start and end time in nanosecond.
-     *
-     * @param startEpochTimeMilli start time since epoch in millisecond
-     * @param startTimeNano start time in nanosecond
-     * @param endTimeNano end time in nanosecond
-     */
-    public static TimingInfo newTimingInfoFullSupport(
-        long startEpochTimeMilli, long startTimeNano, long endTimeNano) {
-        return new TimingInfoFullSupport(Long.valueOf(startEpochTimeMilli), startTimeNano, Long.valueOf(endTimeNano));
-    }
-
-    /**
-     * Returns an instance of {@link TimingInfo} that is not modifiable, given
-     * the start and end nano times.
-     */
-    public static TimingInfo unmodifiableTimingInfo(long startTimeNano, Long endTimeNano) {
-        return new TimingInfoUnmodifiable(null, startTimeNano, endTimeNano);
-    }
-
-    /**
-     * Returns an instance of {@link TimingInfo} that is not modifiable.
-     *
-     * @param startEpochTimeMilli start time since epoch in millisecond
-     * @param startTimeNano start time in nanosecond
-     * @param endTimeNano end time in nanosecond; or null if not known
-     */
-    public static TimingInfo unmodifiableTimingInfo(long startEpochTimeMilli, long startTimeNano, Long endTimeNano) {
-        return new TimingInfoUnmodifiable(startEpochTimeMilli, startTimeNano, endTimeNano);
-    }
-
-    /**
-     * A private ctor to facilitate the deprecation of using millisecond and
-     * migration to using nanosecond for timing measurement.
-     * 
-     * @param startEpochTimeMilli start time since epoch in millisecond
-     * @param startTimeNano start time in nanosecond
-     * @param endTimeNano end time in nanosecond; or null if not known
-     */
-    protected TimingInfo(Long startEpochTimeMilli, long startTimeNano, Long endTimeNano) {
-        this.startEpochTimeMilli = startEpochTimeMilli;
-        this.startTimeNano = startTimeNano;
-        this.endTimeNano = endTimeNano;
-    }
-
-    @Deprecated
-    public final long getStartTime() {
-        return isStartEpochTimeMilliKnown()
-             ? startEpochTimeMilli
-               // best effort even though technically this is incorrect
-             : TimeUnit.NANOSECONDS.toMillis(startTimeNano)
-             ;
-    }
-
-    @Deprecated
-    public final long getStartEpochTimeMilli() {
-        Long v = getStartEpochTimeMilliIfKnown();
-        return v == null ? UNKNOWN : v.longValue();
-    }
-
-    public final Long getStartEpochTimeMilliIfKnown() {
-        return startEpochTimeMilli;
-    }
-
-    public final long getStartTimeNano() {
-        return startTimeNano;
-    }
-
-    @Deprecated
-    public final long getEndTime() {
-        return getEndEpochTimeMilli();
-    }
-
-    @Deprecated
-    public final long getEndEpochTimeMilli() {
-        Long v = getEndEpochTimeMilliIfKnown();
-        return v == null ? UNKNOWN : v.longValue();
-    }
-
-    public final Long getEndEpochTimeMilliIfKnown() {
-        return isStartEpochTimeMilliKnown() && isEndTimeKnown()
-               // make use of the wall clock time and elpased time
-             ? startEpochTimeMilli.longValue()
-                 + TimeUnit.NANOSECONDS.toMillis(endTimeNano.longValue() - startTimeNano)
-             : null;
-    }
-
-    public final long getEndTimeNano() {
-        return endTimeNano == null ? UNKNOWN : endTimeNano;
-    }
-
-    public final Long getEndTimeNanoIfKnown() {
-        return endTimeNano;
-    }
-
-    @Deprecated
-    public final double getTimeTakenMillis() {
-        Double v = getTimeTakenMillisIfKnown();
-        return v == null ? UNKNOWN : v.doubleValue();
-    }
-
-    public final Double getTimeTakenMillisIfKnown() {
-        return isEndTimeKnown() 
-             ? durationMilliOf(startTimeNano, endTimeNano)
-             : null
-             ;
-    }
-
-    /**
-     * Returns the duration in milliseconds as double, preserving the decimal
-     * precision as necessary, for the given start and end time in nanoseconds.
-     */
-    public static double durationMilliOf(long startTimeNano, long endTimeNano) {
-        double micros = (double)TimeUnit.NANOSECONDS.toMicros(endTimeNano - startTimeNano);
-        return micros / 1000.0; // convert microseconds to milliseconds in double rather than long, preserving the precision
-    }
-
-    @Deprecated
-    public final long getElapsedTimeMillis() {
-        Double v = getTimeTakenMillisIfKnown();
-        return v == null ? UNKNOWN : v.longValue();
-    }
-
-    public final boolean isEndTimeKnown() {
-        return endTimeNano != null;
-    }
-
-    public final boolean isStartEpochTimeMilliKnown() {
-        return startEpochTimeMilli != null;
-    }
-
-    public final String toString() {
-        return String.valueOf(getTimeTakenMillis());
-    }
-
-    @Deprecated
-    public void setEndTime(long endTimeMilli) {
-        this.endTimeNano = Long.valueOf(TimeUnit.MILLISECONDS.toNanos(endTimeMilli));
-    }
-
-    public void setEndTimeNano(long endTimeNano) {
-        this.endTimeNano = endTimeNano;
-    }
-
-    public TimingInfo endTiming() {
-        this.endTimeNano = Long.valueOf(System.nanoTime());
-        return this;
-    }
-
-    public void addSubMeasurement(String subMeasurementName, TimingInfo timingInfo) {}
-    public TimingInfo getSubMeasurement(String subMeasurementName) { return null; }
-    public TimingInfo getSubMeasurement(String subMesurementName, int index) { return null; }
-    public TimingInfo getLastSubMeasurement(String subMeasurementName) { return null; }
-    public List<TimingInfo> getAllSubMeasurements(String subMeasurementName) { return null; }
-    public Map<String, List<TimingInfo>> getSubMeasurementsByName() { return Collections.emptyMap(); }
-    public Number getCounter(String key) { return null; }
-    public Map<String, Number> getAllCounters() { return Collections.emptyMap(); }
-    public void setCounter(String key, long count) {}
-    public void incrementCounter(String key) {}
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/TimingInfoUnmodifiable.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/TimingInfoUnmodifiable.java
--- ./src/main/java/com/amazonaws/util/TimingInfoUnmodifiable.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/TimingInfoUnmodifiable.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,57 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.annotation.ThreadSafe;
-
-/**
- * A {@link TimingInfo} that is unmodifiable.
- */
-@ThreadSafe
-final class TimingInfoUnmodifiable extends TimingInfo {
-    /**
-     * @see TimingInfo#unmodifiableTimingInfo(long, Long)
-     * @see TimingInfo#unmodifiableTimingInfo(long, long, Long)
-     * 
-     * @param startEpochTimeMilli
-     *            start time since epoch in millisecond; or null if not known
-     * @param startTimeNano
-     *            start time in nanosecond
-     * @param endTimeNano
-     *            end time in nanosecond; or null if not known
-     */
-    TimingInfoUnmodifiable(Long startEpochTimeMilli, long startTimeNano, Long endTimeNano) {
-        super(startEpochTimeMilli, startTimeNano, endTimeNano);
-    }
-
-    /**
-     * Always throws {@link UnsupportedOperationException}.
-     */
-    @Override public void setEndTime(long _) {
-        throw new UnsupportedOperationException();
-    }
-    /**
-     * Always throws {@link UnsupportedOperationException}.
-     */
-    @Override public void setEndTimeNano(long _) {
-        throw new UnsupportedOperationException();
-    }
-    /**
-     * Always throws {@link UnsupportedOperationException}.
-     */
-    @Override public TimingInfo endTiming() {
-        throw new UnsupportedOperationException();
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/UnreliableFilterInputStream.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/UnreliableFilterInputStream.java
--- ./src/main/java/com/amazonaws/util/UnreliableFilterInputStream.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/UnreliableFilterInputStream.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,167 +0,0 @@
-/*
- * Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.amazonaws.util.json.Jackson;
-
-/**
- * An internal class used solely for the purpose of testing via failure
- * injection.
- */
-public class UnreliableFilterInputStream extends FilterInputStream {
-    /**
-     * Max number of errors that can be triggered.
-     */
-    private int maxNumErrors = 1;
-    /**
-     * Current number of errors that have been triggered.
-     */
-    private int currNumErrors;
-    
-    private int bytesReadBeforeException = 100;
-    private int marked;
-    private int position;
-    // True to throw a FakeIOException; false to throw a RuntimeException
-    private final boolean isFakeIOException;
-    private int resetCount; // number of times the reset method has been called
-    /**
-     * used to control whether an exception would be thrown based on the reset
-     * recurrence; not applicable if set to zero. For example, if
-     * resetIntervalBeforeException == n, the exception can only be thrown
-     * before the n_th reset (or after the n_th minus 1 reset), 2n_th reset (or
-     * after the 2n_th minus 1) reset), etc.
-     */
-    private int resetIntervalBeforeException; 
-
-    public UnreliableFilterInputStream(InputStream in, boolean isFakeIOException) {
-        super(in);
-        this.isFakeIOException = isFakeIOException;
-    }
-
-    @Override
-    public int read() throws IOException {
-        int read = super.read();
-        if (read != -1) position++;
-        triggerError();
-        return read;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        triggerError();
-        int read = super.read(b, off, len);
-        position += read;
-        triggerError();
-        return read;
-    }
-
-    @Override
-    public void mark(int readlimit) {
-        super.mark(readlimit);
-        marked = position;
-    }
-
-    @Override
-    public void reset() throws IOException {
-        resetCount++;
-        super.reset();
-        position = marked;
-    }
-
-    private void triggerError() throws FakeIOException {
-        if (currNumErrors >= maxNumErrors)
-            return;
-
-        if (position >= bytesReadBeforeException) {
-            if (resetIntervalBeforeException > 0
-            &&  resetCount % resetIntervalBeforeException != (resetIntervalBeforeException-1))
-                return;
-            currNumErrors++;
-            if (isFakeIOException)
-                throw new FakeIOException("Fake IO error " + currNumErrors
-                    + " on UnreliableFileInputStream: " + this);
-            else
-                throw new RuntimeException("Injected runtime error " + currNumErrors
-                        + " on UnreliableFileInputStream: " + this);
-        }
-    }
-
-    public int getCurrNumErrors() {
-        return currNumErrors;
-    }
-
-    public int getMaxNumErrors() {
-        return maxNumErrors;
-    }
-
-    public UnreliableFilterInputStream withMaxNumErrors(int maxNumErrors) {
-        this.maxNumErrors = maxNumErrors;
-        return this; 
-    }
-
-    public UnreliableFilterInputStream withBytesReadBeforeException(
-            int bytesReadBeforeException) {
-        this.bytesReadBeforeException = bytesReadBeforeException;
-        return this;
-    }
-
-    public int getBytesReadBeforeException() {
-        return bytesReadBeforeException;
-    }
-
-    /**
-     * @param resetIntervalBeforeException
-     *            used to control whether an exception would be thrown based on
-     *            the reset recurrence; not applicable if set to zero. For
-     *            example, if resetIntervalBeforeException == n, the exception
-     *            can only be thrown before the n_th reset (or after the n_th
-     *            minus 1 reset), 2n_th reset (or after the 2n_th minus 1)
-     *            reset), etc.
-     */
-    public UnreliableFilterInputStream withResetIntervalBeforeException(
-            int resetIntervalBeforeException) {
-        this.resetIntervalBeforeException = resetIntervalBeforeException;
-        return this;
-    }
-
-    public int getResetIntervalBeforeException() {
-        return resetIntervalBeforeException;
-    }
- 
-    public int getMarked() {
-        return marked;
-    }
-
-    public int getPosition() {
-        return position;
-    }
-
-    public boolean isFakeIOException() {
-        return isFakeIOException;
-    }
-
-    public int getResetCount() {
-        return resetCount;
-    }
-    
-    @Override
-    public String toString() {
-        return Jackson.toJsonString(this);
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/util/UriResourcePathUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/UriResourcePathUtils.java
--- ./src/main/java/com/amazonaws/util/UriResourcePathUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/UriResourcePathUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,52 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import com.amazonaws.Request;
-
-public final class UriResourcePathUtils {
-
-    /**
-     * Identifies the static query parameters in Uri resource path for and adds it to
-     * request.
-     *
-     * Returns the updated uriResourcePath.
-     */
-    public static String addStaticQueryParamtersToRequest(final Request<?> request,
-                                                        final String uriResourcePath) {
-
-        if (request == null || uriResourcePath == null) {
-            return null;
-        }
-
-        String resourcePath = uriResourcePath;
-
-        int index = resourcePath.indexOf("?");
-        if (index != -1) {
-            String queryString = resourcePath.substring(index + 1);
-            resourcePath = resourcePath.substring(0, index);
-
-            for (String s : queryString.split("[;&]")) {
-                index = s.indexOf("=");
-                if (index != -1) {
-                    request.addParameter(s.substring(0, index), s.substring(index + 1));
-                } else {
-                    request.addParameter(s, (String)null);
-                }
-            }
-        }
-        return resourcePath;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/URLEncodedUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/URLEncodedUtils.java
--- ./src/main/java/com/amazonaws/util/URLEncodedUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/URLEncodedUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,347 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package com.amazonaws.util;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.BitSet;
-import java.util.List;
-
-import com.amazonaws.annotation.Immutable;
-
-// Copied and extracted from httpcomponents-client-4.3.6.
-/**
- * A collection of utilities for encoding URLs.
- *
- * @since 4.0
- */
-@Immutable
-class URLEncodedUtils {
-    private static final char QP_SEP_A = '&';
-    private static final String NAME_VALUE_SEPARATOR = "=";
-
-    /**
-     * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded}
-     * list of parameters in an HTTP PUT or HTTP POST.
-     *
-     * @param parameters  The parameters to include.
-     * @param charset The encoding to use.
-     * @return An {@code application/x-www-form-urlencoded} string
-     */
-    public static String format(
-            final List <? extends NameValuePair> parameters,
-            final String charset) {
-        return format(parameters, QP_SEP_A, charset);
-    }
-
-    /**
-     * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded}
-     * list of parameters in an HTTP PUT or HTTP POST.
-     *
-     * @param parameters  The parameters to include.
-     * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}.
-     * @param charset The encoding to use.
-     * @return An {@code application/x-www-form-urlencoded} string
-     *
-     * @since 4.3
-     */
-    public static String format(
-            final List <? extends NameValuePair> parameters,
-            final char parameterSeparator,
-            final String charset) {
-        final StringBuilder result = new StringBuilder();
-        for (final NameValuePair parameter : parameters) {
-            final String encodedName = encodeFormFields(parameter.getName(), charset);
-            final String encodedValue = encodeFormFields(parameter.getValue(), charset);
-            if (result.length() > 0) {
-                result.append(parameterSeparator);
-            }
-            result.append(encodedName);
-            if (encodedValue != null) {
-                result.append(NAME_VALUE_SEPARATOR);
-                result.append(encodedValue);
-            }
-        }
-        return result.toString();
-    }
-
-    /**
-     * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded}
-     * list of parameters in an HTTP PUT or HTTP POST.
-     *
-     * @param parameters  The parameters to include.
-     * @param charset The encoding to use.
-     * @return An {@code application/x-www-form-urlencoded} string
-     *
-     * @since 4.2
-     */
-    public static String format(
-            final Iterable<? extends NameValuePair> parameters,
-            final Charset charset) {
-        return format(parameters, QP_SEP_A, charset);
-    }
-
-    /**
-     * Returns a String that is suitable for use as an {@code application/x-www-form-urlencoded}
-     * list of parameters in an HTTP PUT or HTTP POST.
-     *
-     * @param parameters  The parameters to include.
-     * @param parameterSeparator The parameter separator, by convention, {@code '&'} or {@code ';'}.
-     * @param charset The encoding to use.
-     * @return An {@code application/x-www-form-urlencoded} string
-     *
-     * @since 4.3
-     */
-    public static String format(
-            final Iterable<? extends NameValuePair> parameters,
-            final char parameterSeparator,
-            final Charset charset) {
-        final StringBuilder result = new StringBuilder();
-        for (final NameValuePair parameter : parameters) {
-            final String encodedName = encodeFormFields(parameter.getName(), charset);
-            final String encodedValue = encodeFormFields(parameter.getValue(), charset);
-            if (result.length() > 0) {
-                result.append(parameterSeparator);
-            }
-            result.append(encodedName);
-            if (encodedValue != null) {
-                result.append(NAME_VALUE_SEPARATOR);
-                result.append(encodedValue);
-            }
-        }
-        return result.toString();
-    }
-
-    /**
-     * Unreserved characters, i.e. alphanumeric, plus: {@code _ - ! . ~ ' ( ) *}
-     * <p>
-     *  This list is the same as the {@code unreserved} list in
-     *  <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>
-     */
-    private static final BitSet UNRESERVED   = new BitSet(256);
-    /**
-     * Punctuation characters: , ; : $ & + =
-     * <p>
-     * These are the additional characters allowed by userinfo.
-     */
-    private static final BitSet PUNCT        = new BitSet(256);
-    /** Characters which are safe to use in userinfo,
-     * i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation */
-    private static final BitSet USERINFO     = new BitSet(256);
-    /** Characters which are safe to use in a path,
-     * i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation plus / @ */
-    private static final BitSet PATHSAFE     = new BitSet(256);
-    /** Characters which are safe to use in a query or a fragment,
-     * i.e. {@link #RESERVED} plus {@link #UNRESERVED} */
-    private static final BitSet URIC     = new BitSet(256);
-
-    /**
-     * Reserved characters, i.e. {@code ;/?:@&=+$,[]}
-     * <p>
-     *  This list is the same as the {@code reserved} list in
-     *  <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>
-     *  as augmented by
-     *  <a href="http://www.ietf.org/rfc/rfc2732.txt">RFC 2732</a>
-     */
-    private static final BitSet RESERVED     = new BitSet(256);
-
-
-    /**
-     * Safe characters for x-www-form-urlencoded data, as per java.net.URLEncoder and browser behaviour,
-     * i.e. alphanumeric plus {@code "-", "_", ".", "*"}
-     */
-    private static final BitSet URLENCODER   = new BitSet(256);
-
-    static {
-        // unreserved chars
-        // alpha characters
-        for (int i = 'a'; i <= 'z'; i++) {
-            UNRESERVED.set(i);
-        }
-        for (int i = 'A'; i <= 'Z'; i++) {
-            UNRESERVED.set(i);
-        }
-        // numeric characters
-        for (int i = '0'; i <= '9'; i++) {
-            UNRESERVED.set(i);
-        }
-        UNRESERVED.set('_'); // these are the charactes of the "mark" list
-        UNRESERVED.set('-');
-        UNRESERVED.set('.');
-        UNRESERVED.set('*');
-        URLENCODER.or(UNRESERVED); // skip remaining unreserved characters
-        UNRESERVED.set('!');
-        UNRESERVED.set('~');
-        UNRESERVED.set('\'');
-        UNRESERVED.set('(');
-        UNRESERVED.set(')');
-        // punct chars
-        PUNCT.set(',');
-        PUNCT.set(';');
-        PUNCT.set(':');
-        PUNCT.set('$');
-        PUNCT.set('&');
-        PUNCT.set('+');
-        PUNCT.set('=');
-        // Safe for userinfo
-        USERINFO.or(UNRESERVED);
-        USERINFO.or(PUNCT);
-
-        // URL path safe
-        PATHSAFE.or(UNRESERVED);
-        PATHSAFE.set('/'); // segment separator
-        PATHSAFE.set(';'); // param separator
-        PATHSAFE.set(':'); // rest as per list in 2396, i.e. : @ & = + $ ,
-        PATHSAFE.set('@');
-        PATHSAFE.set('&');
-        PATHSAFE.set('=');
-        PATHSAFE.set('+');
-        PATHSAFE.set('$');
-        PATHSAFE.set(',');
-
-        RESERVED.set(';');
-        RESERVED.set('/');
-        RESERVED.set('?');
-        RESERVED.set(':');
-        RESERVED.set('@');
-        RESERVED.set('&');
-        RESERVED.set('=');
-        RESERVED.set('+');
-        RESERVED.set('$');
-        RESERVED.set(',');
-        RESERVED.set('['); // added by RFC 2732
-        RESERVED.set(']'); // added by RFC 2732
-
-        URIC.or(RESERVED);
-        URIC.or(UNRESERVED);
-    }
-
-    private static final int RADIX = 16;
-
-    private static String urlEncode(
-            final String content,
-            final Charset charset,
-            final BitSet safechars,
-            final boolean blankAsPlus) {
-        if (content == null) {
-            return null;
-        }
-        final StringBuilder buf = new StringBuilder();
-        final ByteBuffer bb = charset.encode(content);
-        while (bb.hasRemaining()) {
-            final int b = bb.get() & 0xff;
-            if (safechars.get(b)) {
-                buf.append((char) b);
-            } else if (blankAsPlus && b == ' ') {
-                buf.append('+');
-            } else {
-                buf.append("%");
-                final char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, RADIX));
-                final char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, RADIX));
-                buf.append(hex1);
-                buf.append(hex2);
-            }
-        }
-        return buf.toString();
-    }
-
-    /**
-     * Encode/escape www-url-form-encoded content.
-     * <p>
-     * Uses the {@link #URLENCODER} set of characters, rather than
-     * the {@link #UNRSERVED} set; this is for compatibilty with previous
-     * releases, URLEncoder.encode() and most browsers.
-     *
-     * @param content the content to encode, will convert space to '+'
-     * @param charset the charset to use
-     * @return encoded string
-     */
-    private static String encodeFormFields(final String content, final String charset) {
-        if (content == null) {
-            return null;
-        }
-        return urlEncode(content, charset != null ? Charset.forName(charset) : StringUtils.UTF8, URLENCODER, true);
-    }
-
-    /**
-     * Encode/escape www-url-form-encoded content.
-     * <p>
-     * Uses the {@link #URLENCODER} set of characters, rather than
-     * the {@link #UNRSERVED} set; this is for compatibilty with previous
-     * releases, URLEncoder.encode() and most browsers.
-     *
-     * @param content the content to encode, will convert space to '+'
-     * @param charset the charset to use
-     * @return encoded string
-     */
-    private static String encodeFormFields (final String content, final Charset charset) {
-        if (content == null) {
-            return null;
-        }
-        return urlEncode(content, charset != null ? charset : StringUtils.UTF8, URLENCODER, true);
-    }
-
-    /**
-     * Encode a String using the {@link #USERINFO} set of characters.
-     * <p>
-     * Used by URIBuilder to encode the userinfo segment.
-     *
-     * @param content the string to encode, does not convert space to '+'
-     * @param charset the charset to use
-     * @return the encoded string
-     */
-    static String encUserInfo(final String content, final Charset charset) {
-        return urlEncode(content, charset, USERINFO, false);
-    }
-
-    /**
-     * Encode a String using the {@link #URIC} set of characters.
-     * <p>
-     * Used by URIBuilder to encode the query and fragment segments.
-     *
-     * @param content the string to encode, does not convert space to '+'
-     * @param charset the charset to use
-     * @return the encoded string
-     */
-    static String encUric(final String content, final Charset charset) {
-        return urlEncode(content, charset, URIC, false);
-    }
-
-    /**
-     * Encode a String using the {@link #PATHSAFE} set of characters.
-     * <p>
-     * Used by URIBuilder to encode path segments.
-     *
-     * @param content the string to encode, does not convert space to '+'
-     * @param charset the charset to use
-     * @return the encoded string
-     */
-    static String encPath(final String content, final Charset charset) {
-        return urlEncode(content, charset, PATHSAFE, false);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/ValidationUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ValidationUtils.java
--- ./src/main/java/com/amazonaws/util/ValidationUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/ValidationUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,93 +0,0 @@
-/*
- * Copyright 2015-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.util.Collection;
-
-/**
- * Useful utilities to validate dependencies
- */
-public class ValidationUtils {
-
-    /**
-     * Asserts that the given object is non-null and returns it.
-     *
-     * @param object
-     *         Object to assert on
-     * @param fieldName
-     *         Field name to display in exception message if null
-     * @return Object if non null
-     * @throws IllegalArgumentException
-     *         If object was null
-     */
-    public static <T> T assertNotNull(T object, String fieldName) throws IllegalArgumentException {
-        if (object == null) {
-            throw new IllegalArgumentException(String.format("%s cannot be null", fieldName));
-        }
-        return object;
-    }
-
-    /**
-     * Asserts that all of the objects are null.
-     *
-     * @throws IllegalArgumentException
-     *         if any object provided was NOT null.
-     */
-    public static void assertAllAreNull(String messageIfNull, Object... objects) throws IllegalArgumentException {
-        for (Object object : objects) {
-            if (object != null) {
-                throw new IllegalArgumentException(messageIfNull);
-            }
-        }
-    }
-
-    /**
-     * Asserts that the given number is positive (non-negative and non-zero).
-     *
-     * @param num       Number to validate
-     * @param fieldName Field name to display in exception message if not positive.
-     * @return Number if positive.
-     */
-    public static int assertIsPositive(int num, String fieldName) {
-        if (num <= 0) {
-            throw new IllegalArgumentException(String.format("%s must be positive", fieldName));
-        }
-        return num;
-    }
-
-    public static <T extends Collection<?>> T assertNotEmpty(T collection, String fieldName) throws IllegalArgumentException{
-        assertNotNull(collection, fieldName);
-        if (collection.isEmpty()) {
-            throw new IllegalArgumentException(String.format("%s cannot be empty", fieldName));
-        }
-        return collection;
-    }
-
-    public static <T> T[] assertNotEmpty(T[] array, String fieldName) throws IllegalArgumentException {
-        assertNotNull(array, fieldName);
-        if (array.length == 0) {
-            throw new IllegalArgumentException(String.format("%s cannot be empty", fieldName));
-        }
-        return array;
-    }
-
-    public static String assertStringNotEmpty(String string, String fieldName) throws IllegalArgumentException {
-        assertNotNull(string, fieldName);
-        if (string.isEmpty()) {
-            throw new IllegalArgumentException(String.format("%s cannot be empty", fieldName));
-        }
-        return string;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/VersionInfoUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/VersionInfoUtils.java
--- ./src/main/java/com/amazonaws/util/VersionInfoUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/VersionInfoUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,298 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.InputStream;
-import java.util.Properties;
-import java.util.jar.JarInputStream;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.amazonaws.annotation.ThreadSafe;
-import com.amazonaws.internal.config.InternalConfig;
-
-import static com.amazonaws.util.IOUtils.closeQuietly;
-
-/**
- * Utility class for accessing AWS SDK versioning information.
- */
-@ThreadSafe
-public class VersionInfoUtils {
-    /** The AWS SDK version info file with SDK versioning info */
-    static final String VERSION_INFO_FILE = "/com/amazonaws/sdk/versionInfo.properties";
-
-    /** SDK version info */
-    private static volatile String version;
-
-    /** SDK platform info */
-    private static volatile String platform;
-
-    /** User Agent info */
-    private static volatile String userAgent;
-
-    /** Shared logger for any issues while loading version information */
-    private static final Log log = LogFactory.getLog(VersionInfoUtils.class);
-
-    private static final String UNKNOWN = "unknown";
-
-    /**
-     * Returns the current version for the AWS SDK in which this class is
-     * running. Version information is obtained from from the
-     * versionInfo.properties file which the AWS Java SDK build process
-     * generates.
-     *
-     * @return The current version for the AWS SDK, if known, otherwise
-     *         returns a string indicating that the version information is
-     *         not available.
-     */
-    public static String getVersion() {
-        if (version == null) {
-            synchronized(VersionInfoUtils.class) {
-                if (version == null)
-                    initializeVersion();
-            }
-        }
-        return version;
-    }
-
-    /**
-     * Returns the current platform for the AWS SDK in which this class is
-     * running. Version information is obtained from from the
-     * versionInfo.properties file which the AWS Java SDK build process
-     * generates.
-     *
-     * @return The current platform for the AWS SDK, if known, otherwise
-     *         returns a string indicating that the platform information is
-     *         not available.
-     */
-    public static String getPlatform() {
-        if (platform == null) {
-            synchronized(VersionInfoUtils.class) {
-                if (platform == null)
-                    initializeVersion();
-            }
-        }
-        return platform;
-    }
-
-     /**
-     * @return Returns the User Agent string to be used when communicating with
-	 * the AWS services.  The User Agent encapsulates SDK, Java, OS and
-	 * region information.
-     */
-    public static String getUserAgent() {
-        if (userAgent == null) {
-            synchronized(VersionInfoUtils.class) {
-                if (userAgent == null)
-                    initializeUserAgent();
-            }
-        }
-        return userAgent;
-    }
-
-   /**
-     * Loads the versionInfo.properties file from the AWS Java SDK and
-     * stores the information so that the file doesn't have to be read the
-     * next time the data is needed.
-     */
-    private static void initializeVersion() {
-        InputStream inputStream = ClassLoaderHelper.getResourceAsStream(
-                VERSION_INFO_FILE, true, VersionInfoUtils.class);
-        Properties versionInfoProperties = new Properties();
-        try {
-            if (inputStream == null)
-                throw new Exception(VERSION_INFO_FILE + " not found on classpath");
-
-            versionInfoProperties.load(inputStream);
-            version = versionInfoProperties.getProperty("version");
-            platform = versionInfoProperties.getProperty("platform");
-        } catch (Exception e) {
-            log.info("Unable to load version information for the running SDK: " + e.getMessage());
-            version = "unknown-version";
-            platform = "java";
-        } finally {
-            closeQuietly(inputStream, log);
-        }
-    }
-
-    /**
-     * Initializes the user agent string by loading a template from
-     * {@code InternalConfig} and filling in the detected version/platform
-     * info.
-     */
-    private static void initializeUserAgent() {
-        userAgent = userAgent();
-    }
-
-    static String userAgent() {
-
-        String ua = InternalConfig.Factory.getInternalConfig()
-                .getUserAgentTemplate();
-
-        if (ua == null) {
-            return "aws-sdk-java";
-        }
-
-        ua = ua
-            .replace("{platform}",  StringUtils.lowerCase(getPlatform()))
-            .replace("{version}", getVersion())
-            .replace("{os.name}", replaceSpaces(System.getProperty("os.name")))
-            .replace("{os.version}", replaceSpaces(System.getProperty("os.version")))
-            .replace("{java.vm.name}", replaceSpaces(System.getProperty("java.vm.name")))
-            .replace("{java.vm.version}", replaceSpaces(System.getProperty("java.vm.version")))
-            .replace("{java.version}", replaceSpaces(System.getProperty("java.version")));
-
-        if (ua.contains("{additional.languages}")) {
-            ua = ua.replace("{additional.languages}", getAdditionalJvmLanguages());
-        }
-
-
-        String language = System.getProperty("user.language");
-        String region = System.getProperty("user.region");
-
-        String languageAndRegion = "";
-        if (language != null && region != null) {
-            languageAndRegion =
-                    " " + replaceSpaces(language) + "_" + replaceSpaces(region);
-        }
-        ua = ua.replace("{language.and.region}", languageAndRegion);
-
-        return ua;
-    }
-
-    /**
-     * Replace any spaces in the input with underscores.
-     *
-     * @param input the input
-     * @return the input with spaces replaced by underscores
-     */
-    private static String replaceSpaces(final String input) {
-        return input == null ? UNKNOWN : input.replace(' ', '_');
-    }
-
-    private static String getAdditionalJvmLanguages() {
-        StringBuilder versions = new StringBuilder();
-        concat(versions, scalaVersion(), " ");
-        concat(versions, clojureVersion(), " ");
-        concat(versions, groovyVersion(), " ");
-        concat(versions, jythonVersion(), " ");
-        concat(versions, jrubyVersion(), " ");
-        concat(versions, kotlinVersion(), " ");
-        return versions.toString();
-    }
-
-    private static String scalaVersion() {
-        return languageVersion("scala", "scala.util.Properties", "versionNumberString", true);
-    }
-
-    private static String clojureVersion() {
-        return languageVersion("clojure", "clojure.core$clojure_version", "invokeStatic", true);
-    }
-
-    private static String groovyVersion() {
-        return languageVersion("groovy", "groovy.lang.GroovySystem", "getVersion", true);
-    }
-
-    private static String jythonVersion() {
-        return languageVersion("jython", "org.python.Version", "PY_VERSION", false);
-    }
-
-    private static String jrubyVersion() {
-        return languageVersion("jruby", "org.jruby.runtime.Constants", "VERSION", false);
-    }
-
-    /**
-     * Attempt to determine if Kotlin is on the classpath and if so what version is in use.
-     * Can do this by either using the KotlinVersion class that was introduced in 1.1 or
-     * via looking at the JAR's manifest versions for earlier versions.
-     *
-     * @return Kotlin version if any, else empty string
-     */
-    private static String kotlinVersion() {
-        String version = kotlinVersionByClass();
-        return version.equals("") ? kotlinVersionByJar() : version;
-    }
-
-    private static String kotlinVersionByClass() {
-        StringBuilder kotlinVersion = new StringBuilder("");
-        try {
-            Class<?> versionClass = Class.forName("kotlin.KotlinVersion");
-            kotlinVersion.append("kotlin");
-            String version = versionClass.getField("CURRENT").get(null).toString();
-            concat(kotlinVersion, version, "/");
-        } catch (ClassNotFoundException e) {
-            //ignore
-        } catch (Exception e) {
-            if (log.isTraceEnabled()){
-                log.trace("Exception attempting to get Kotlin version.", e);
-            }
-
-        }
-        return kotlinVersion.toString();
-    }
-
-    private static String kotlinVersionByJar() {
-        StringBuilder kotlinVersion = new StringBuilder("");
-        JarInputStream kotlinJar = null;
-        try {
-            Class<?> kotlinUnit = Class.forName("kotlin.Unit");
-            kotlinVersion.append("kotlin");
-            kotlinJar = new JarInputStream(kotlinUnit.getProtectionDomain().getCodeSource().getLocation().openStream());
-            String version = kotlinJar.getManifest().getMainAttributes().getValue("Implementation-Version");
-            concat(kotlinVersion, version, "/");
-        } catch (ClassNotFoundException e) {
-            //Ignore
-        } catch (Exception e) {
-            if (log.isTraceEnabled()) {
-                log.trace("Exception attempting to get Kotlin version.", e);
-            }
-        } finally {
-            closeQuietly(kotlinJar, log);
-        }
-        return kotlinVersion.toString();
-    }
-
-    /**
-     * Attempt to determine if this language exists on the classpath and what it's version is
-     * @param language the name of the language
-     * @param className a class of that lanauge that exposes runtime version information
-     * @param methodOrFieldName the static field or method name that holds the version number
-     * @param isMethod whether the above is a field or method
-     * @return the version number or empty string if the language does not exist on the classpath
-     */
-    private static String languageVersion(String language, String className, String methodOrFieldName, boolean isMethod) {
-        StringBuilder sb = new StringBuilder();
-        try {
-            Class<?> clz = Class.forName(className);
-            sb.append(language);
-            String version = isMethod ? (String) clz.getMethod(methodOrFieldName).invoke(null) : (String) clz.getField(methodOrFieldName).get(null);
-            concat(sb, version, "/");
-        } catch (ClassNotFoundException e) {
-            //Ignore
-        } catch (Exception e) {
-            if (log.isTraceEnabled()){
-                log.trace("Exception attempting to get " + language + " version.", e);
-            }
-        }
-        return sb.toString();
-    }
-
-    private static void concat(StringBuilder prefix, String suffix, String separator) {
-        if (suffix != null && !suffix.isEmpty()) {
-            prefix.append(separator).append(suffix);
-        }
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/XmlUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/XmlUtils.java
--- ./src/main/java/com/amazonaws/util/XmlUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/XmlUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,68 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- * 
- *  http://aws.amazon.com/apache2.0
- * 
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.xml.stream.XMLInputFactory;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-public class XmlUtils {
-
-    /**
-     * Shared factory for creating XML event readers
-     */
-    private static final ThreadLocal<XMLInputFactory> xmlInputFactory = new ThreadLocal<XMLInputFactory>() {
-        @Override
-        protected XMLInputFactory initialValue() {
-            return createXmlInputFactory();
-        }
-    };
-
-    public static XMLReader parse(InputStream in, ContentHandler handler)
-        throws SAXException, IOException {
-
-        XMLReader reader = XMLReaderFactory.createXMLReader();
-        reader.setContentHandler(handler);
-        reader.parse(new InputSource(in));
-        in.close();
-        return reader;
-    }
-
-    /**
-     * @return A {@link ThreadLocal} copy of {@link XMLInputFactory}.
-     */
-    public static XMLInputFactory getXmlInputFactory() {
-        return xmlInputFactory.get();
-    }
-
-    /**
-     * Disables certain dangerous features that attempt to automatically fetch DTDs
-     *
-     * See <a href="https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet">OWASP XXE Cheat Sheet</a>
-     */
-    private static XMLInputFactory createXmlInputFactory() {
-        XMLInputFactory factory = XMLInputFactory.newInstance();
-        factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
-        factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
-        return factory;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/XMLWriter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/XMLWriter.java
--- ./src/main/java/com/amazonaws/util/XMLWriter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/XMLWriter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,195 +0,0 @@
-/*
- * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.nio.ByteBuffer;
-import java.util.Date;
-import java.util.Stack;
-
-import com.amazonaws.SdkClientException;
-
-/**
- * Utility for creating easily creating XML documents, one element at a time.
- */
-public class XMLWriter {
-
-    /** Standard XML prolog to add to the beginning of each XML document. */
-    private static final String PROLOG = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-
-    /** The writer to which the XML document created by this writer will be written. */
-    private final Writer writer;
-
-    /** Optional XML namespace attribute value to include in the root element. */
-    private final String xmlns;
-
-    private Stack<String> elementStack = new Stack<String>();
-    private boolean rootElement = true;
-
-
-    /**
-     * Creates a new XMLWriter, ready to write an XML document to the specified
-     * writer.  The XML document will not specify an xmlns attribute.
-     *
-     * @param w
-     *            The writer this XMLWriter will write to.
-     */
-    public XMLWriter(Writer w) {
-        this(w, null);
-    }
-
-    /**
-     * Creates a new XMLWriter, ready to write an XML document to the specified
-     * writer. The root element in the XML document will specify an xmlns
-     * attribute with the specified namespace parameter.
-     *
-     * @param w
-     *            The writer this XMLWriter will write to.
-     * @param xmlns
-     *            The XML namespace to include in the xmlns attribute of the
-     *            root element.
-     */
-    public XMLWriter(Writer w, String xmlns) {
-        this.writer = w;
-        this.xmlns = xmlns;
-        append(PROLOG);
-    }
-
-    /**
-     * Starts a new element with the specified name at the current position in
-     * the in-progress XML document.
-     *
-     * @param element
-     *            The name of the new element.
-     *
-     * @return This XMLWriter so that additional method calls can be chained
-     *         together.
-     */
-    public XMLWriter startElement(String element) {
-        append("<" + element);
-        if (rootElement && xmlns != null) {
-            append(" xmlns=\"" + xmlns + "\"");
-            rootElement = false;
-        }
-        append(">");
-        elementStack.push(element);
-        return this;
-    }
-
-    /**
-     * Closes the last opened element at the current position in the in-progress
-     * XML document.
-     *
-     * @return This XMLWriter so that additional method calls can be chained
-     *         together.
-     */
-    public XMLWriter endElement() {
-        String lastElement = elementStack.pop();
-        append("</" + lastElement + ">");
-        return this;
-    }
-
-    /**
-     * Adds the specified value as text to the current position of the in
-     * progress XML document.
-     *
-     * @param s
-     *            The text to add to the XML document.
-     *
-     * @return This XMLWriter so that additional method calls can be chained
-     *         together.
-     */
-    public XMLWriter value(String s) {
-        append(escapeXMLEntities(s));
-        return this;
-    }
-
-    /**
-     * Adds the specified value as Base64 encoded text to the current position of the in
-     * progress XML document.
-     *
-     * @param b
-     *            The binary data to add to the XML document.
-     *
-     * @return This XMLWriter so that additional method calls can be chained
-     *         together.
-     */
-    public XMLWriter value(ByteBuffer b) {
-        append(escapeXMLEntities(Base64.encodeAsString(BinaryUtils.copyBytesFrom(b))));
-        return this;
-    }
-
-    /**
-     * Adds the specified date as text to the current position of the
-     * in-progress XML document.
-     *
-     * @param date
-     *            The date to add to the XML document.
-     *
-     * @return This XMLWriter so that additional method calls can be chained
-     *         together.
-     */
-    public XMLWriter value(Date date) {
-        append(escapeXMLEntities(StringUtils.fromDate(date)));
-        return this;
-    }
-
-    /**
-     * Adds the string representation of the specified object to the current
-     * position of the in progress XML document.
-     *
-     * @param obj
-     *            The object to translate to a string and add to the XML
-     *            document.
-     *
-     * @return This XMLWriter so that additional method calls can be chained
-     *         together.
-     */
-    public XMLWriter value(Object obj) {
-        append(escapeXMLEntities(obj.toString()));
-        return this;
-    }
-
-    private void append(String s) {
-        try {
-            writer.append(s);
-        } catch (IOException e) {
-            throw new SdkClientException("Unable to write XML document", e);
-        }
-    }
-    
-    private String escapeXMLEntities(String s) {
-    	/** 
-    	 * Unescape any escaped characters.
-    	 */
-    	if (s.contains("&")) {
-        	s = s.replace("&quot;", "\"");
-        	s = s.replace("&apos;", "'");
-        	s = s.replace("&lt;", "<");
-        	s = s.replace("&gt;", ">");
-        	// Ampersands should always be the last to unescape
-        	s = s.replace("&amp;", "&");
-    	}
-    	// Ampersands should always be the first to escape
-    	s = s.replace("&", "&amp;");
-    	s = s.replace("\"", "&quot;");
-    	s = s.replace("'", "&apos;");
-    	s = s.replace("<", "&lt;");
-    	s = s.replace(">", "&gt;");
-    	return s;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/util/XpathUtils.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/XpathUtils.java
--- ./src/main/java/com/amazonaws/util/XpathUtils.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/util/XpathUtils.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,607 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazonaws.util;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-/**
- * Utility methods for extracting data from XML documents using Xpath
- * expressions.
- */
-public class XpathUtils {
-
-    /** The default property name to load the Xalan DTM manager. */
-    private static final String DTM_MANAGER_DEFAULT_PROP_NAME = "com.sun.org.apache.xml.internal.dtm.DTMManager";
-
-    /** The default property name to load the Xalan Document Builder Factory. */
-    private static final String DOCUMENT_BUILDER_FACTORY_PROP_NAME = "javax.xml.parsers.DocumentBuilderFactory";
-
-    /** The FQCN of the desired DocumentBuilderFactory implementation. */
-    private static final String DOCUMENT_BUILDER_FACTORY_IMPL_CLASS_NAME = "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl";
-
-    /** The FQCN of the internal XPathContext class. */
-    private static final String XPATH_CONTEXT_CLASS_NAME = "com.sun.org.apache.xpath.internal.XPathContext";
-
-    /** The FQCN of the desired DTMManager implementation. */
-    private static final String DTM_MANAGER_IMPL_CLASS_NAME = "com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault";
-
-    private static final Log log = LogFactory.getLog(XpathUtils.class);
-
-    private static final ErrorHandler ERROR_HANDLER = new ErrorHandler() {
-
-        @Override
-        public void warning(SAXParseException e) throws SAXException {
-            if (log.isDebugEnabled()) {
-                log.debug("xml parse warning: " + e.getMessage(), e);
-            }
-        }
-
-        @Override
-        public void fatalError(SAXParseException e) throws SAXException {
-            throw e;
-        }
-
-        @Override
-        public void error(SAXParseException e) throws SAXException {
-            if (log.isDebugEnabled()) {
-                log.debug("xml parse error: " + e.getMessage(), e);
-            }
-        }
-    };
-
-    /**
-     * Used to optimize performance by avoiding expensive file access every time
-     * a DTMManager is constructed as a result of constructing a Xalan xpath
-     * context!
-     */
-    private static void speedUpDTMManager() throws Exception {
-        // https://github.com/aws/aws-sdk-java/issues/238
-        // http://stackoverflow.com/questions/6340802/java-xpath-apache-jaxp-implementation-performance
-        if (System.getProperty(DTM_MANAGER_DEFAULT_PROP_NAME) == null) {
-            Class<?> XPathContextClass = Class.forName(XPATH_CONTEXT_CLASS_NAME);
-            Method getDTMManager = XPathContextClass.getMethod("getDTMManager");
-            Object XPathContext = XPathContextClass.newInstance();
-            Object dtmManager = getDTMManager.invoke(XPathContext);
-
-            if (DTM_MANAGER_IMPL_CLASS_NAME.equals(dtmManager.getClass().getName())) {
-                // This would avoid the file system to be accessed every time
-                // the internal XPathContext is instantiated.
-                System.setProperty(DTM_MANAGER_DEFAULT_PROP_NAME,
-                        DTM_MANAGER_IMPL_CLASS_NAME);
-            }
-        }
-    }
-
-    /**
-     * Used to optimize performance by avoiding expensive file access every time
-     * a DocumentBuilderFactory is constructed as a result of constructing a
-     * Xalan document factory.
-     */
-    private static void speedUpDcoumentBuilderFactory() {
-        if (System.getProperty(DOCUMENT_BUILDER_FACTORY_PROP_NAME) == null) {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            if (DOCUMENT_BUILDER_FACTORY_IMPL_CLASS_NAME.equals(factory.getClass().getName())) {
-                // This would avoid the file system to be accessed every time
-                // the internal DocumentBuilderFactory is instantiated.
-                System.setProperty(DOCUMENT_BUILDER_FACTORY_PROP_NAME,
-                        DOCUMENT_BUILDER_FACTORY_IMPL_CLASS_NAME);
-            }
-        }
-    }
-
-    // static initialization block to conservatively speed things up whenever we
-    // can
-    static {
-        try {
-            speedUpDcoumentBuilderFactory();
-        } catch(Throwable t) {
-            log.debug("Ingore failure in speeding up DocumentBuilderFactory", t);
-        }
-        try {
-            speedUpDTMManager();
-        } catch(Throwable t) {
-            log.debug("Ingore failure in speeding up DTMManager", t);
-        }
-    }
-
-    // XPath is not thread safe and not reentrant.
-    /**
-     * Returns a new instance of XPath, which is not thread safe and not
-     * reentrant.
-     */
-    public static XPath xpath() {
-        return XPathFactory.newInstance().newXPath();
-    }
-
-    /**
-     * This method closes the given input stream upon completion.
-     */
-    public static Document documentFrom(InputStream is)
-            throws SAXException, IOException, ParserConfigurationException {
-        is = new NamespaceRemovingInputStream(is);
-        // DocumentBuilderFactory is not thread safe
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        DocumentBuilder builder = factory.newDocumentBuilder();
-        // ensure that parser writes error/warning messages to the logger
-        // rather than stderr
-        builder.setErrorHandler(ERROR_HANDLER);
-        Document doc = builder.parse(is);
-        is.close();
-        return doc;
-    }
-
-    public static Document documentFrom(String xml) throws SAXException,
-            IOException, ParserConfigurationException {
-        return documentFrom(new ByteArrayInputStream(xml.getBytes(StringUtils.UTF8)));
-    }
-
-    public static Document documentFrom(URL url) throws SAXException,
-            IOException, ParserConfigurationException {
-        return documentFrom(url.openStream());
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the results as a
-     * Double.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Double result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Double asDouble(String expression, Node node)
-            throws XPathExpressionException {
-        return asDouble(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asDouble(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Double asDouble(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String doubleString = evaluateAsString(expression, node, xpath);
-        return (isEmptyString(doubleString)) ? null : Double.parseDouble(doubleString);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * string.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The string result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static String asString(String expression, Node node)
-            throws XPathExpressionException {
-        return evaluateAsString(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asString(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static String asString(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        return evaluateAsString(expression, node, xpath);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as an
-     * Integer.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Integer result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Integer asInteger(String expression, Node node)
-            throws XPathExpressionException {
-        return asInteger(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asInteger(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Integer asInteger(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String intString = evaluateAsString(expression, node, xpath);
-        return (isEmptyString(intString)) ? null : Integer.parseInt(intString);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * Boolean.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Boolean result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Boolean asBoolean(String expression, Node node)
-            throws XPathExpressionException {
-        return asBoolean(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asBoolean(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Boolean asBoolean(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String booleanString = evaluateAsString(expression, node, xpath);
-        return (isEmptyString(booleanString)) ? null : Boolean.parseBoolean(booleanString);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * Float.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Float result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Float asFloat(String expression, Node node)
-            throws XPathExpressionException {
-        return asFloat(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asFloat(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Float asFloat(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String floatString = evaluateAsString(expression, node, xpath);
-        return (isEmptyString(floatString)) ? null : Float.valueOf(floatString);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * Long.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Long result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Long asLong(String expression, Node node)
-            throws XPathExpressionException {
-        return asLong(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asLong(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Long asLong(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String longString = evaluateAsString(expression, node, xpath);
-        return (isEmptyString(longString)) ? null : Long.parseLong(longString);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * Byte.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Byte result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Byte asByte(String expression, Node node)
-            throws XPathExpressionException {
-        return asByte(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asByte(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Byte asByte(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String byteString = evaluateAsString(expression, node, xpath);
-        return (isEmptyString(byteString)) ? null : Byte.valueOf(byteString);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * Date. Assumes that the node's text is formatted as an ISO 8601 date, as
-     * specified by xs:dateTime.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Date result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Date asDate(String expression, Node node)
-            throws XPathExpressionException {
-        return asDate(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asDate(String, Node)} but allows an xpath to be passed
-     * in explicitly for reuse.
-     */
-    public static Date asDate(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String dateString = evaluateAsString(expression, node, xpath);
-        if (isEmptyString(dateString)) return null;
-
-        try {
-            return DateUtils.parseISO8601Date(dateString);
-        } catch (Exception e) {
-            log.warn("Unable to parse date '" + dateString + "':  " + e.getMessage(), e);
-            return null;
-        }
-    }
-
-    /**
-     * Evaluates the specified xpath expression, base64 decodes the data and
-     * returns the result as a ByteBuffer.
-     * <p>
-     * This method can be expensive as a new xpath is instantiated per
-     * invocation. Consider passing in the xpath explicitly via {
-     * {@link #asDouble(String, Node, XPath)} instead.  Note {@link XPath} is
-     * not thread-safe and not reentrant.
-     *
-     * @param expression
-     *            The Xpath expression to evaluate.
-     * @param node
-     *            The node on which to evaluate the expression.
-     *
-     * @return A ByteBuffer of base64 decoded data from the result of evaluating
-     *         the specified Xpath expression.
-     *
-     * @throws XPathExpressionException
-     *             If there are any problems evaluating the Xpath expression.
-     */
-    public static ByteBuffer asByteBuffer(String expression, Node node)
-            throws XPathExpressionException {
-        return asByteBuffer(expression, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asByteBuffer(String, Node)} but allows an xpath to be
-     * passed in explicitly for reuse.
-     */
-    public static ByteBuffer asByteBuffer(String expression, Node node, XPath xpath)
-            throws XPathExpressionException {
-        String base64EncodedString = evaluateAsString(expression, node, xpath);
-        if (isEmptyString(base64EncodedString)) return null;
-
-        if (!isEmpty(node)) {
-            byte[] decodedBytes = Base64.decode(base64EncodedString);
-            return ByteBuffer.wrap(decodedBytes);
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if the specified node is null or has no children.
-     *
-     * @param node
-     *            The node to test.
-     *
-     * @return True if the specified node is null or has no children.
-     */
-    public static boolean isEmpty(Node node) {
-        return (node == null);
-    }
-
-    /**
-     * Evaluates the specified XPath expression and returns the result as a
-     * Node.
-     *
-     * @param nodeName
-     *            The XPath expression to evaluate.
-     * @param node
-     *            The node to run the expression on.
-     *
-     * @return The Node result.
-     *
-     * @throws XPathExpressionException
-     *             If there was a problem processing the specified XPath
-     *             expression.
-     */
-    public static Node asNode(String nodeName, Node node)
-            throws XPathExpressionException {
-        return asNode(nodeName, node, xpath());
-    }
-
-    /**
-     * Same as {@link #asNode(String, Node)} but allows an xpath to be
-     * passed in explicitly for reuse.
-     */
-    public static Node asNode(String nodeName, Node node, XPath xpath)
-            throws XPathExpressionException {
-        if (node == null) return null;
-        return (Node) xpath.evaluate(nodeName, node, XPathConstants.NODE);
-    }
-
-    /**
-     * Returns the length of the specified node list.
-     *
-     * @param list
-     *            The node list to measure.
-     *
-     * @return The length of the specified node list.
-     */
-    public static int nodeLength(NodeList list) {
-        return list == null ? 0 : list.getLength();
-    }
-
-    /**
-     * Evaluates the specified expression on the specified node and returns the
-     * result as a String.
-     *
-     * @param expression
-     *            The Xpath expression to evaluate.
-     * @param node
-     *            The node on which to evaluate the expression.
-     *
-     * @return The result of evaluating the specified expression, or null if the
-     *         evaluation didn't return any result.
-     *
-     * @throws XPathExpressionException
-     *             If there are any problems evaluating the Xpath expression.
-     */
-    private static String evaluateAsString(String expression, Node node,
-            XPath xpath) throws XPathExpressionException {
-        if (isEmpty(node)) return null;
-
-        if (!expression.equals(".")) {
-            /*
-             * If the expression being evaluated doesn't select a node, we want
-             * to return null to distinguish between cases where a node isn't
-             * present (which should be represented as null) and when a node is
-             * present, but empty (which should be represented as the empty
-             * string).
-             *
-             * We skip this test if the expression is "." since we've already
-             * checked that the node exists.
-             */
-            if (asNode(expression, node, xpath) == null) return null;
-        }
-
-        String s = xpath.evaluate(expression, node);
-
-        return s.trim();
-    }
-
-    /**
-     * Returns true if the specified string is null or empty.
-     *
-     * @param s
-     *            The string to test.
-     * @return True if the specified string is null or empty.
-     */
-    private static boolean isEmptyString(String s) {
-        return s == null || s.trim().length() == 0;
-    }
-}
\ No newline at end of file
diff -Nau8r ./src/main/java/com/amazonaws/waiters/AcceptorPathMatcher.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/AcceptorPathMatcher.java
--- ./src/main/java/com/amazonaws/waiters/AcceptorPathMatcher.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/AcceptorPathMatcher.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,91 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.fasterxml.jackson.databind.JsonNode;
-
-@SdkProtectedApi
-public class AcceptorPathMatcher {
-
-    /**
-     * PathAll matcher that checks if each element of the final
-     * result matches the expected result
-     *
-     * @param expectedResult Expected result given by the waiter definition
-     * @param finalResult    Final result of the resource got by the execution
-     *                       of the JmesPath expression given by the waiter
-     *                       definition
-     * @return True if all elements of the final result matches
-     * the expected result, False otherwise
-     */
-    public static boolean pathAll(JsonNode expectedResult, JsonNode finalResult) {
-        if (finalResult.isNull()) {
-            return false;
-        }
-        if (!finalResult.isArray()) {
-            throw new RuntimeException("Expected an array");
-        }
-        for (JsonNode element : finalResult) {
-            if (!element.equals(expectedResult)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * PathAny matcher that checks if any element of the final
-     * result matches the expected result
-     *
-     * @param expectedResult Expected result given by the waiter definition
-     * @param finalResult    Final result of the resource got by the execution
-     *                       of the JmesPath expression given by the waiter
-     *                       definition
-     * @return True if any single element of the final result matches
-     * the expected result, False if none matched
-     */
-    public static boolean pathAny(JsonNode expectedResult, JsonNode finalResult) {
-        if (finalResult.isNull()) {
-            return false;
-        }
-        if (!finalResult.isArray()) {
-            throw new RuntimeException("Expected an array");
-        }
-        for (JsonNode element : finalResult) {
-            if (element.equals(expectedResult)) {
-                return true;
-            }
-        }
-        return false;
-
-    }
-
-    /**
-     * Path matcher that checks if the final result
-     * matches the expected result
-     *
-     * @param expectedResult Expected result given by the waiter definition
-     * @param finalResult    Final result of the resource got by the execution
-     *                       of the JmesPath expression given by the waiter
-     *                       definition
-     * @return True if the final result matches the expected result,
-     * False otherwise
-     */
-    public static boolean path(JsonNode expectedResult, JsonNode finalResult) {
-        return finalResult.equals(expectedResult);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/CompositeAcceptor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/CompositeAcceptor.java
--- ./src/main/java/com/amazonaws/waiters/CompositeAcceptor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/CompositeAcceptor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,90 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.SdkInternalApi;
-import com.amazonaws.util.ValidationUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SdkInternalApi
-class CompositeAcceptor<Output> {
-
-    /**
-     * List of acceptors defined for each waiter
-     */
-    private List<WaiterAcceptor<Output>> acceptors = new ArrayList<WaiterAcceptor<Output>>();
-
-    /**
-     * Constructs a new Composite Acceptor with the given list of acceptors.
-     * Throws an assertion exception if the acceptor list is empty or null
-     *
-     * @param acceptors List of acceptors defined for each waiter. It shouldn't
-     *                  be null or empty
-     */
-    public CompositeAcceptor(List<WaiterAcceptor<Output>> acceptors) {
-        this.acceptors = ValidationUtils.assertNotEmpty(acceptors, "acceptors");
-    }
-
-    /**
-     * @return List of acceptors defined for each waiter
-     */
-    public List<WaiterAcceptor<Output>> getAcceptors() {
-        return this.acceptors;
-    }
-
-    /**
-     * Compares the response against each response acceptor and returns
-     * the state of the acceptor it matches on. If none is matched, returns
-     * retry state by default
-     *
-     * @param response Response object got by executing the specified
-     *                 waiter operation
-     * @return (Enum) Corresponding waiter state defined by the acceptor or
-     * retry state if none matched
-     */
-    public WaiterState accepts(Output response) {
-        for (WaiterAcceptor<Output> acceptor : acceptors) {
-            if (acceptor.matches(response)) {
-                return acceptor.getState();
-            }
-        }
-        return WaiterState.RETRY;
-
-    }
-
-    /**
-     * Compares the exception thrown against each exception acceptor and
-     * returns the state of the acceptor it matches on. If none is
-     * matched, it rethrows the exception to the caller
-     *
-     * @param exception Exception thrown by executing the specified
-     *                  waiter operation
-     * @return (Enum) Corresponding waiter state defined by the acceptor or
-     * rethrows the exception back to the caller if none matched
-     * @throws Exception
-     */
-    public WaiterState accepts(AmazonServiceException exception) throws AmazonServiceException {
-        for (WaiterAcceptor<Output> acceptor : acceptors) {
-            if (acceptor.matches(exception)) {
-                return acceptor.getState();
-            }
-        }
-        throw exception;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/FixedDelayStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/FixedDelayStrategy.java
--- ./src/main/java/com/amazonaws/waiters/FixedDelayStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/FixedDelayStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-public class FixedDelayStrategy implements PollingStrategy.DelayStrategy{
-
-    /**
-     * Represents default delay time in seconds
-     */
-    private final int defaultDelayInSeconds;
-
-    /**
-     * Constructs a new FixedDelayStrategy with the given
-     * default delay time
-     *
-     * @param defaultDelayInSeconds
-     */
-    public FixedDelayStrategy(int defaultDelayInSeconds) {
-        this.defaultDelayInSeconds = defaultDelayInSeconds;
-    }
-
-    /**
-     * Defines a default way of delaying the polling bound by
-     * the default delay associated with the corresponding
-     * waiter definition
-     *
-     * @param pollingStrategyContext Provides the polling context required to define custom delay
-     * @throws InterruptedException
-     */
-    @Override
-    public void delayBeforeNextRetry(PollingStrategyContext pollingStrategyContext) throws InterruptedException {
-        Thread.sleep(defaultDelayInSeconds * 1000);
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/HttpFailureStatusAcceptor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/HttpFailureStatusAcceptor.java
--- ./src/main/java/com/amazonaws/waiters/HttpFailureStatusAcceptor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/HttpFailureStatusAcceptor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,41 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-@SdkProtectedApi
-public class HttpFailureStatusAcceptor<Output> extends WaiterAcceptor<Output> {
-
-    private final int expectedStatusCode;
-    private final WaiterState waiterState;
-
-    public HttpFailureStatusAcceptor(int expectedStatusCode, WaiterState waiterState) {
-        this.expectedStatusCode = expectedStatusCode;
-        this.waiterState = waiterState;
-    }
-
-    @Override
-    public boolean matches(AmazonServiceException ase) {
-        return expectedStatusCode == ase.getStatusCode();
-    }
-
-    @Override
-    public WaiterState getState() {
-        return waiterState;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/HttpSuccessStatusAcceptor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/HttpSuccessStatusAcceptor.java
--- ./src/main/java/com/amazonaws/waiters/HttpSuccessStatusAcceptor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/HttpSuccessStatusAcceptor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-@SdkProtectedApi
-public class HttpSuccessStatusAcceptor<Output> extends WaiterAcceptor<Output>{
-
-    private final WaiterState waiterState;
-
-    public HttpSuccessStatusAcceptor(WaiterState waiterState) {
-        this.waiterState = waiterState;
-    }
-
-    @Override
-    public boolean matches(Output output) {
-        return true;
-    }
-
-    @Override
-    public WaiterState getState() {
-        return waiterState;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/MaxAttemptsRetryStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/MaxAttemptsRetryStrategy.java
--- ./src/main/java/com/amazonaws/waiters/MaxAttemptsRetryStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/MaxAttemptsRetryStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,47 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-public class MaxAttemptsRetryStrategy implements PollingStrategy.RetryStrategy {
-
-    /**
-     * Represents default number of maximum attempts allowed
-     * for polling
-     */
-    private final int defaultMaxAttempts;
-
-    /**
-     * Constructs a new MaxAttemptsRetryStrategy with the given
-     * default number of attempts
-     *
-     * @param defaultMaxAttempts
-     */
-    public MaxAttemptsRetryStrategy(int defaultMaxAttempts) {
-        this.defaultMaxAttempts = defaultMaxAttempts;
-    }
-
-    /**
-     * Default way of checking if polling should be retried
-     * or fast failed
-     *
-     * @param pollingStrategyContext Provides the polling context required to make the retry decision
-     * @return false if the number of re
-     */
-    @Override
-    public boolean shouldRetry(PollingStrategyContext pollingStrategyContext) {
-        return pollingStrategyContext.getRetriesAttempted() < defaultMaxAttempts;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/NoOpWaiterHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/NoOpWaiterHandler.java
--- ./src/main/java/com/amazonaws/waiters/NoOpWaiterHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/NoOpWaiterHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkInternalApi;
-
-@SdkInternalApi
-public class NoOpWaiterHandler extends WaiterHandler<AmazonWebServiceRequest>{
-
-    @Override
-    public void onWaitSuccess(AmazonWebServiceRequest request) {
-    }
-
-    @Override
-    public void onWaitFailure(Exception e) {
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/PollingStrategyContext.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/PollingStrategyContext.java
--- ./src/main/java/com/amazonaws/waiters/PollingStrategyContext.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/PollingStrategyContext.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-@SdkProtectedApi
-public class PollingStrategyContext {
-
-    /**
-     * Represents the original input of the operation.
-     */
-    private final AmazonWebServiceRequest originalRequest;
-
-    /**
-     * Represents the number of retries made so far
-     */
-    private final int retriesAttempted;
-
-    /**
-     * Constructs a new polling strategy context with the given
-     * request and retries attempted required for custom polling
-     *
-     * @param originalRequest
-     * @param retriesAttempted
-     */
-    PollingStrategyContext(AmazonWebServiceRequest originalRequest, int retriesAttempted) {
-        this.originalRequest = originalRequest;
-        this.retriesAttempted = retriesAttempted;
-    }
-
-    /**
-     * @return Original input of the operation.
-     */
-    public AmazonWebServiceRequest getOriginalRequest() {
-        return originalRequest;
-    }
-
-    /**
-     * @return Number of retries attempted
-     */
-    public int getRetriesAttempted() {
-        return retriesAttempted;
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/PollingStrategy.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/PollingStrategy.java
--- ./src/main/java/com/amazonaws/waiters/PollingStrategy.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/PollingStrategy.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,93 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-public class PollingStrategy{
-
-    /**
-     * Condition on whether polling should be retried.
-     */
-    private final RetryStrategy retryStrategy;
-
-    /**
-     * Delay strategy to control the sleep time between retry attempts.
-     */
-    private final DelayStrategy delayStrategy;
-
-    /**
-     * Constructs a new PollingStrategy with RetryStrategy
-     * and DelayStrategy defined
-     *
-     * @param retryStrategy Retry condition on whether polling should be retried.
-     *                      If null value is specified, the SDK' default retry
-     *                      condition is used.
-     */
-    public PollingStrategy(RetryStrategy retryStrategy, DelayStrategy delayStrategy) {
-        this.retryStrategy = retryStrategy;
-        this.delayStrategy = delayStrategy;
-    }
-
-    /**
-     * Returns the retry condition included in this Polling Strategy.
-     *
-     * @return The retry condition included in this Polling Strategy.
-     */
-    RetryStrategy getRetryStrategy() {
-        return this.retryStrategy;
-    }
-
-    /**
-     * Returns the delay strategy included in this Polling Strategy.
-     *
-     * @return The delay strategy included in this Polling Strategy.
-     */
-    DelayStrategy getDelayStrategy() {
-        return this.delayStrategy;
-    }
-
-    /**
-     * The hook for providing custom condition on whether polling of a resource
-     * should be retried.
-     */
-    public interface RetryStrategy {
-        /**
-         * Returns whether polling of a resource should be retried according to the
-         * given polling context.
-         *
-         * @param pollingStrategyContext Provides the polling context required to make the retry decision
-         * @return True if it should be retried.
-         * @see PollingStrategyContext
-         */
-        boolean shouldRetry(PollingStrategyContext pollingStrategyContext);
-    }
-
-    /**
-     * The hook for providing custom delay strategy to control the sleep time
-     * between retries.
-     */
-    public interface DelayStrategy {
-
-        /**
-         * Defines the custom delay strategy to control the sleep time
-         *
-         * @param pollingStrategyContext Provides the polling context required to define custom delay
-         * @throws InterruptedException
-         * @see PollingStrategyContext
-         */
-        void delayBeforeNextRetry(PollingStrategyContext pollingStrategyContext) throws InterruptedException;
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/SdkFunction.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/SdkFunction.java
--- ./src/main/java/com/amazonaws/waiters/SdkFunction.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/SdkFunction.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,33 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-@SdkProtectedApi
-public interface SdkFunction<Input, Output> {
-
-    /**
-     * Abstract method that makes a call to the operation
-     * specified by the waiter by taking the corresponding
-     * input and returns the corresponding output
-     *
-     * @param input Corresponding request for the operation
-     * @return Corresponding result of the operation
-     */
-    Output apply(Input input);
-}
-
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterAcceptor.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterAcceptor.java
--- ./src/main/java/com/amazonaws/waiters/WaiterAcceptor.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterAcceptor.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,60 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-@SdkProtectedApi
-public abstract class WaiterAcceptor<Output> {
-
-    /**
-     * Default method definition that matches the response
-     * state with the expected state defined by the acceptor.
-     * Overriden by each acceptor definition of matches.
-     *
-     * @param output Response got by the execution of the operation
-     * @return False by default.
-     * When overriden, returns True if it matches, False
-     * otherwise
-     */
-    public boolean matches(Output output) {
-        return false;
-    }
-
-    /**
-     * Default method definition that matches the exception
-     * with the expected state defined by the acceptor.
-     * Overriden by each acceptor definition of matches.
-     *
-     * @param output Exception thrown by the execution of the operation
-     * @return False by default.
-     * When overriden, returns True if it matches, False
-     * otherwise
-     */
-    public boolean matches(AmazonServiceException output) {
-        return false;
-    }
-
-    /**
-     * Abstract method to fetch the corresponding state
-     *
-     * @return Corresponding state of the resource
-     */
-    public abstract WaiterState getState();
-}
-
-
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterBuilder.java
--- ./src/main/java/com/amazonaws/waiters/WaiterBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-
-@SdkProtectedApi
-public class WaiterBuilder<Input extends AmazonWebServiceRequest, Output> {
-
-    private SdkFunction<Input, Output> sdkFunction;
-
-    private List<WaiterAcceptor<Output>> acceptors = new ArrayList<WaiterAcceptor<Output>>();
-
-    private PollingStrategy defaultPollingStrategy;
-
-    private ExecutorService executorService;
-
-    public WaiterBuilder<Input, Output> withSdkFunction(SdkFunction<Input, Output> sdkFunction) {
-        this.sdkFunction = sdkFunction;
-        return this;
-    }
-
-    public WaiterBuilder<Input, Output> withAcceptors(WaiterAcceptor<Output>... acceptors) {
-        Collections.addAll(this.acceptors, acceptors);
-        return this;
-    }
-
-    public WaiterBuilder<Input, Output> withDefaultPollingStrategy(PollingStrategy pollingStrategy) {
-        this.defaultPollingStrategy = pollingStrategy;
-        return this;
-    }
-
-    public WaiterBuilder<Input, Output> withExecutorService(ExecutorService executorService) {
-        this.executorService = executorService;
-        return this;
-    }
-
-    public List<WaiterAcceptor<Output>> getAcceptor() {
-        return this.acceptors;
-    }
-
-    public SdkFunction<Input, Output> getSdkFunction() {
-        return this.sdkFunction;
-    }
-
-    PollingStrategy getDefaultPollingStrategy() {
-        return this.defaultPollingStrategy;
-    }
-
-    public ExecutorService getExecutorService() {
-        return this.executorService;
-    }
-
-    public Waiter<Input> build() {
-        return new WaiterImpl<Input, Output>(this);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterExecutionBuilder.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterExecutionBuilder.java
--- ./src/main/java/com/amazonaws/waiters/WaiterExecutionBuilder.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterExecutionBuilder.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,76 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkProtectedApi;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SdkProtectedApi
-public class WaiterExecutionBuilder<Input extends AmazonWebServiceRequest, Output> {
-
-    private SdkFunction<Input, Output> sdkFunction;
-
-    private Input request;
-
-    private PollingStrategy pollingStrategy;
-
-    private List<WaiterAcceptor<Output>> acceptors = new ArrayList<WaiterAcceptor<Output>>();
-
-    public WaiterExecutionBuilder<Input, Output> withSdkFunction(SdkFunction sdkFunction) {
-        this.sdkFunction = sdkFunction;
-        return this;
-    }
-
-    public WaiterExecutionBuilder<Input, Output> withRequest(Input request) {
-        this.request = request;
-        return this;
-    }
-
-
-    public WaiterExecutionBuilder<Input, Output> withPollingStrategy(PollingStrategy pollingStrategy) {
-        this.pollingStrategy = pollingStrategy;
-        return this;
-    }
-
-    public WaiterExecutionBuilder<Input, Output> withAcceptors(List<WaiterAcceptor<Output>> acceptors) {
-        this.acceptors = acceptors;
-        return this;
-    }
-
-    public Input getRequest() {
-        return this.request;
-    }
-
-    public List<WaiterAcceptor<Output>> getAcceptorsList() {
-        return this.acceptors;
-    }
-
-    public SdkFunction<Input, Output> getSdkFunction() {
-        return this.sdkFunction;
-    }
-
-    public PollingStrategy getPollingStrategy() {
-        return this.pollingStrategy;
-    }
-
-    public WaiterExecution<Input, Output> build() {
-        return new WaiterExecution<Input, Output>(this);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterExecution.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterExecution.java
--- ./src/main/java/com/amazonaws/waiters/WaiterExecution.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterExecution.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,125 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.*;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.util.ValidationUtils;
-
-@SdkProtectedApi
-public class WaiterExecution<Input extends AmazonWebServiceRequest, Output> {
-
-    /**
-     * Resource specific function that makes a call to the
-     * operation specified by the waiter
-     */
-    private final SdkFunction<Input, Output> sdkFunction;
-
-    /**
-     * Represents the input of the operation.
-     */
-    private final Input request;
-
-    /**
-     * List of acceptors defined for each waiter
-     */
-    private final CompositeAcceptor<Output> acceptor;
-
-    /**
-     * Custom polling strategy as given by the end users
-     */
-    private final PollingStrategy pollingStrategy;
-
-    /**
-     * Constructs a new waiter with all the parameters defined
-     * in the WaiterExecutionBuilder
-     *
-     * @param waiterExecutionBuilder Contains all the parameters required to construct a
-     *                               new waiter
-     */
-    public WaiterExecution(WaiterExecutionBuilder<Input, Output> waiterExecutionBuilder) {
-        this.sdkFunction = ValidationUtils.assertNotNull(waiterExecutionBuilder.getSdkFunction(), "sdkFunction");
-        this.request = ValidationUtils.assertNotNull(waiterExecutionBuilder.getRequest(), "request");
-        this.acceptor = new CompositeAcceptor<Output>(ValidationUtils.assertNotNull(waiterExecutionBuilder.getAcceptorsList(), "acceptors"));
-        this.pollingStrategy = ValidationUtils.assertNotNull(waiterExecutionBuilder.getPollingStrategy(), "pollingStrategy");
-    }
-
-    /**
-     * Polls until a specified resource transitions into either success or failure state or
-     * until the specified number of retries has been made.
-     *
-     * @return True if the resource transitions into desired state.
-     * @throws AmazonServiceException       If the service exception thrown doesn't match any of the expected
-     *                                      exceptions, it's re-thrown.
-     * @throws WaiterUnrecoverableException If the resource transitions into a failure/unexpected state.
-     * @throws WaiterTimedOutException      If the resource doesn't transition into the desired state
-     *                                      even after a certain number of retries.
-     */
-    public boolean pollResource() throws AmazonServiceException, WaiterTimedOutException, WaiterUnrecoverableException {
-        int retriesAttempted = 0;
-        while (true) {
-            switch (getCurrentState()) {
-                case SUCCESS:
-                    return true;
-                case FAILURE:
-                    throw new WaiterUnrecoverableException("Resource never entered the desired state as it failed.");
-                case RETRY:
-                    PollingStrategyContext pollingStrategyContext = new PollingStrategyContext(request, retriesAttempted);
-                    if (pollingStrategy.getRetryStrategy().shouldRetry(pollingStrategyContext)) {
-                        safeCustomDelay(pollingStrategyContext);
-                        retriesAttempted++;
-                    } else {
-
-                        throw new WaiterTimedOutException("Reached maximum attempts without transitioning to the desired state");
-                    }
-                    break;
-            }
-
-        }
-    }
-
-    /**
-     * Fetches the current state of the resource based on the acceptor it matches
-     *
-     * @return Current state of the resource
-     * @throws Exception
-     */
-    private WaiterState getCurrentState() throws AmazonServiceException {
-        try {
-            return acceptor.accepts(sdkFunction.apply(request));
-        } catch (AmazonServiceException amazonServiceException) {
-            return acceptor.accepts(amazonServiceException);
-        }
-
-    }
-
-    /**
-     * Calls the custom delay strategy to control the sleep time
-     *
-     * @param pollingStrategyContext Provides the polling strategy context.
-     *                               Includes request and number of retries
-     *                               attempted so far.
-     */
-    private void safeCustomDelay(PollingStrategyContext pollingStrategyContext) {
-        try {
-            pollingStrategy.getDelayStrategy().delayBeforeNextRetry(pollingStrategyContext);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterHandler.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterHandler.java
--- ./src/main/java/com/amazonaws/waiters/WaiterHandler.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterHandler.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,30 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonWebServiceRequest;
-
-/**
- * Callbacks are executed synchronously. That is the same thread the waiter
- * completes on and it's not submitted back to the executor.
- */
-public abstract class WaiterHandler<Input extends AmazonWebServiceRequest> {
-
-    public abstract void onWaitSuccess(Input request);
-
-    public abstract void onWaitFailure(Exception e);
-}
-
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterImpl.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterImpl.java
--- ./src/main/java/com/amazonaws/waiters/WaiterImpl.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterImpl.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,122 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonWebServiceRequest;
-import com.amazonaws.annotation.SdkProtectedApi;
-import com.amazonaws.util.ValidationUtils;
-
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-@SdkProtectedApi
-public class WaiterImpl<Input extends AmazonWebServiceRequest, Output> implements Waiter<Input>{
-
-    /**
-     * Represents the operation function
-     */
-    private final SdkFunction<Input, Output> sdkFunction;
-
-    /**
-     * List of acceptors
-     */
-    private final List<WaiterAcceptor<Output>> acceptors;
-
-    /**
-     * Represents the default polling strategy
-     */
-    private final PollingStrategy defaultPollingStrategy;
-
-    private final ExecutorService executorService;
-
-    /**
-     * Constructs a new waiter with the given internal parameters
-     *
-     * @param waiterBuilder Takes in default parameters and builds a
-     *                      basic waiter. Excludes request and custom
-     *                      polling strategy parameters.
-     */
-    @SdkProtectedApi
-    public WaiterImpl(WaiterBuilder<Input, Output> waiterBuilder) {
-        this.sdkFunction = ValidationUtils.assertNotNull(waiterBuilder.getSdkFunction(), "sdkFunction");
-        this.acceptors = ValidationUtils.assertNotNull(waiterBuilder.getAcceptor(), "acceptors");
-        this.defaultPollingStrategy = ValidationUtils.assertNotNull(waiterBuilder.getDefaultPollingStrategy(), "defaultPollingStrategy");
-        this.executorService = ValidationUtils.assertNotNull(waiterBuilder.getExecutorService(), "executorService");
-    }
-
-    /**
-     * Polls synchronously until it is determined that the resource
-     * transitioned into the desired state or not.
-     *
-     * @param waiterParameters Custom provided parameters. Includes request and
-     *                         optional custom polling strategy
-     * @throws AmazonServiceException       If the service exception thrown doesn't match any of the expected
-     *                                      exceptions, it's re-thrown.
-     * @throws WaiterUnrecoverableException If the resource transitions into a failure/unexpected state.
-     * @throws WaiterTimedOutException      If the resource doesn't transition into the desired state
-     *                                      even after a certain number of retries.
-     */
-    public void run(WaiterParameters<Input> waiterParameters)
-            throws AmazonServiceException, WaiterTimedOutException, WaiterUnrecoverableException {
-
-        ValidationUtils.assertNotNull(waiterParameters, "waiterParameters");
-        @SuppressWarnings("unchecked")
-        Input request = (Input) ValidationUtils.assertNotNull(waiterParameters.getRequest(), "request").clone();
-        request.getRequestClientOptions().appendUserAgent("waiter-request");
-        WaiterExecution<Input, Output> waiterExecution = new WaiterExecutionBuilder<Input, Output>()
-                .withRequest(request)
-                .withPollingStrategy(waiterParameters.getPollingStrategy() != null ? waiterParameters.getPollingStrategy() : defaultPollingStrategy)
-                .withAcceptors(acceptors)
-                .withSdkFunction(sdkFunction)
-                .build();
-
-        waiterExecution.pollResource();
-
-    }
-
-    /**
-     * Polls asynchronously until it is determined that the resource
-     * transitioned into the desired state or not. Includes additional
-     * callback.
-     *
-     * @param waiterParameters Custom provided parameters. Includes request and
-     *                         optional custom polling strategy
-     * @param callback         Custom callback
-     * @return Future object that holds the result of an asynchronous
-     * computation of waiter
-     */
-    public Future<Void> runAsync(final WaiterParameters<Input> waiterParameters, final WaiterHandler callback)
-            throws AmazonServiceException, WaiterTimedOutException, WaiterUnrecoverableException {
-
-        return executorService.submit(new java.util.concurrent.Callable<Void>() {
-            @Override
-            public Void call() throws Exception {
-                try {
-                    run(waiterParameters);
-                    callback.onWaitSuccess(waiterParameters.getRequest());
-                } catch (Exception ex) {
-                    callback.onWaitFailure(ex);
-
-                    throw ex;
-                }
-                return null;
-            }
-        });
-
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/Waiter.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/Waiter.java
--- ./src/main/java/com/amazonaws/waiters/Waiter.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/Waiter.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonServiceException;
-import com.amazonaws.AmazonWebServiceRequest;
-
-import java.util.concurrent.Future;
-
-public interface Waiter<Input extends AmazonWebServiceRequest> {
-
-    /**
-     * Polls synchronously until it is determined that the resource
-     * transitioned into the desired state or not.
-     *
-     * @param waiterParameters Custom provided parameters. Includes request and
-     *                         optional custom polling strategy
-     * @throws AmazonServiceException       If the service exception thrown doesn't match any of the expected
-     *                                      exceptions, it's re-thrown.
-     * @throws WaiterUnrecoverableException If the resource transitions into a failure/unexpected state.
-     * @throws WaiterTimedOutException      If the resource doesn't transition into the desired state
-     *                                      even after a certain number of retries.
-     */
-    void run(WaiterParameters<Input> waiterParameters)
-            throws AmazonServiceException, WaiterTimedOutException, WaiterUnrecoverableException;
-
-    /**
-     * Polls asynchronously until it is determined that the resource
-     * transitioned into the desired state or not. Includes additional
-     * callback.
-     *
-     * @param waiterParameters Custom provided parameters. Includes request and
-     *                         optional custom polling strategy
-     * @param callback         Custom callback
-     * @return Future object that holds the result of an asynchronous
-     * computation of waiter
-     */
-    Future<Void> runAsync(final WaiterParameters<Input> waiterParameters, final WaiterHandler callback)
-            throws AmazonServiceException, WaiterTimedOutException, WaiterUnrecoverableException;
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterParameters.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterParameters.java
--- ./src/main/java/com/amazonaws/waiters/WaiterParameters.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterParameters.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,89 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.AmazonWebServiceRequest;
-
-public final class WaiterParameters<Input extends AmazonWebServiceRequest> {
-
-    /**
-     * Represents the input of the operation.
-     */
-    private final Input request;
-
-    /**
-     * Represents the custom polling strategy. Will be null
-     * if not defined
-     */
-    private final PollingStrategy pollingStrategy;
-
-    public WaiterParameters() {
-        this.request = null;
-        this.pollingStrategy = null;
-    }
-
-    public WaiterParameters(Input request) {
-        this.request = request;
-        this.pollingStrategy = null;
-    }
-
-    /**
-     * Constructs a new WaiterParameters with the given request
-     * and polling strategy
-     *
-     * @param request         Input of the operation
-     * @param pollingStrategy Custom polling strategy
-     * @return WaiterParameters object with custom polling strategy defined
-     */
-    private WaiterParameters(Input request, PollingStrategy pollingStrategy) {
-        this.request = request;
-        this.pollingStrategy = pollingStrategy;
-    }
-
-    /**
-     * Constructs a new WaiterParameters with the given request
-     *
-     * @param request Input of the operation
-     * @return WaiterParameters Object
-     */
-    public WaiterParameters<Input> withRequest(Input request) {
-        return new WaiterParameters<Input>(request, this.pollingStrategy);
-    }
-
-    /**
-     * Constructs a new WaiterParameters with the given polling strategy
-     *
-     * @param pollingStrategy Custom polling strategy
-     * @return WaiterParameters Object
-     */
-    public WaiterParameters<Input> withPollingStrategy(PollingStrategy pollingStrategy) {
-        return new WaiterParameters<Input>(this.request, pollingStrategy);
-    }
-
-    /**
-     * @return Input of the operation
-     */
-    public Input getRequest() {
-        return this.request;
-    }
-
-    /**
-     * @return Custom Polling Strategy
-     */
-    public PollingStrategy getPollingStrategy() {
-        return this.pollingStrategy;
-    }
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterState.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterState.java
--- ./src/main/java/com/amazonaws/waiters/WaiterState.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterState.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,27 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.annotation.SdkProtectedApi;
-
-@SdkProtectedApi
-public enum WaiterState {
-    /**
-     * Three different states a resource can be based
-     * on the waiter definition
-     */
-    SUCCESS, RETRY, FAILURE
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterTimedOutException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterTimedOutException.java
--- ./src/main/java/com/amazonaws/waiters/WaiterTimedOutException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterTimedOutException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.SdkClientException;
-
-public class WaiterTimedOutException extends SdkClientException {
-
-    /**
-     * Constructs a new WaiterTimedOutException with the specified error
-     * message.
-     *
-     * @param message Describes the error encountered.
-     */
-    public WaiterTimedOutException(String message) {
-        super(message);
-    }
-
-}
diff -Nau8r ./src/main/java/com/amazonaws/waiters/WaiterUnrecoverableException.java /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterUnrecoverableException.java
--- ./src/main/java/com/amazonaws/waiters/WaiterUnrecoverableException.java	2018-03-16 22:25:16.000000000 -0700
+++ /home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/waiters/WaiterUnrecoverableException.java	1969-12-31 16:00:00.000000000 -0800
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazonaws.waiters;
-
-import com.amazonaws.SdkClientException;
-
-public class WaiterUnrecoverableException extends SdkClientException {
-
-    /**
-     * Constructs a new WaiterUnrecoverableException with the specified error
-     * message.
-     *
-     * @param message Describes the error encountered.
-     */
-    public WaiterUnrecoverableException(String message) {
-        super(message);
-    }
-
-}
